size_t und std::vector<bool>

Technipion

Erfahrenes Mitglied
Hallo Welt,
ich habe gerade einen Codeschnipsel geschrieben, in dem ich mit std::vector<bool> gearbeitet habe. Im Stile des Clean Code und natürlich 100% C++14-konform :D habe ich dabei an diversen Stellen size_t benutzt.
Der Typ von size_t ist ja laut Standard so definiert,
Unsigned integral type
Alias of one of the fundamental unsigned integer types.

It is a type able to represent the size of any object in bytes: size_t is the type returned by the sizeof operator and is widely used in the standard library to represent sizes and counts.

In <cstring>, it is used as the type of the parameter num in the functions memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpy and strxfrm, which in all cases it is used to specify the maximum number of bytes or characters the function has to affect.

It is also used as the return type for strcspn, strlen, strspn and strxfrm to return sizes and lengths.
http://www.cplusplus.com/reference/cstring/size_t/
dass die Größe eines jeden Objektes in Bytes damit gemessen werden kann. Auf der anderen Seite ist std::vector<bool> so definiert,
Vector of bool
This is a specialized version of vector, which is used for elements of type bool and optimizes for space.

It behaves like the unspecialized version of vector, with the following changes:
  • The storage is not necessarily an array of bool values, but the library implementation may optimize storage so that each value is stored in a single bit.
http://www.cplusplus.com/reference/vector/vector-bool/
dass die Speicherung einzelner boolean-Werte in ihrem Platzbedarf soweit wie möglich optimiert werden kann. Meiner Erfahrung nach macht g++ das auch: Wenn ich 500 Wahrheitswerte speichere, beträgt der notwendige Speicherplatz nur etwa 64 Bytes.
Jetzt kam mir natürlich eine Frage in den Sinn. Wenn ich ein bestimmtes Bit über den []-Operator abfrage, benutze ich einen Index vom Typ size_t. Allerdings garantiert size_t mir ja nur, jedes Byte des Containers adressieren zu können.
Ich weiß dass es auf einem "normalen" 64-Bit System und "sinnvoll" gewähltem size_t (z.B. unsigned long) praktisch kein Problem geben sollte. Aber zumindest theoretisch könnten einem bei std::vector<bool> doch die Adressen ausgehen, oder?

Habt ihr vielleicht irgendwelches Background-Wissen oder Vermutungen dazu?

Und ja, ich weiß dass std::vector<bool> ziemlich verhasst ist. War aber für meinen Anwendungsfall einfach perfekt.

Gruß Technipion
 
Hi

Wenn ich dich richtig verstehe, ist deine Sorge, dass bei grossen std::vector<bool> size_t einen Overflow hat, bevor er die letzten Elemente erreicht?
Theoretisch ja. Aber das Problem tritt schon beim Einfügen auf:
http://en.cppreference.com/w/cpp/container/vector/size
size ist die Anzahl Elemente (und nicht effektive Grösse) des Vektors.
D.h. du bekämest schon beim Einfügen Probleme (und nicht erst beim Auslesen).

Ich denke tatsächlich, dass Overflows möglich sind. Aber das ist ja bei Computern nicht unüblich (siehe auch Dateigrössenbeschränkungen und Konsorten). Beim Vektor hört es in der Realität aber ja oft schon vor size_t auf - wegen OS und anderen Beschränkungen.

Aber interessante Überlegung - die Ungenauigkeiten der Computer sind immer interessant :)

Gruss
cwriter
 
Hi

Erstens, bitte nicht auf cplusplus.com verlassen. Das ist a) nichts offizielles und b) nachweislich voll mit Fehlern.

Im eigentlichen Standard ist size_t (falls ich auf die Schnelle nichts übersehen habe) gar nicht speziell definiert, außer "nebenbei" dass es eben für Parameter von new, Returnwerte von sizeof usw. verwendet wird, größere Objekte illformed sind usw.

Zum vector<bool>, ganz versteh ich das Problem nicht. Du machst dir Sorgen, dass die Implementierung von vector<bool> mehr Elemente als size_t erlauben könnte, bzw. nicht prüfen könnte ob das Bytearray drinnen max. ein Achtel Byte vom maximalen size_t-Wert annimmt?

...

Erstes "Problem", size_t ist soweit relevant dass das Vector-Objekt und auch der innen dynamisch allokierte Speicher nicht mehr als size_t Byte haben können. Die (aktuelle/maximale) Anzahl der indizierbaren Elemente eines Vectors (also size und max_size) haben den Typ vector<...>::size_type, nicht size_t. Außerdem gibt es die Methode vector<...>::max_size(), die auch niedrigere Werte als den maximalen Typwert liefern kann.

Ein Vector, der mehr Einfügungen als diese (selbst festgelegten) Beschränkungen erlaubt, hat einen Bug, nicht mehr und nicht weniger.
Ein paar Auszüge aus dem Source von vector<bool>, mit ein paar eigenen Kommentaren:
C++:
typedef unsigned long _Bit_type;
//Intern also ein Array von ulongs, weil bool-Arrays ja eben Verschwendung wären

enum { _S_word_bit = int(__CHAR_BIT__ * sizeof(_Bit_type)) };
// _S_word_bit = Wie viel Bit in ein internes Arrayelement passen

typedef size_t size_type;

size_type max_size() const _GLIBCXX_NOEXCEPT
{
    const size_type __isize = __gnu_cxx::__numeric_traits<difference_type>::__max - int(_S_word_bit) + 1;
    const size_type __asize = _Bit_alloc_traits::max_size(_M_get_Bit_allocator());
    return (__asize <= __isize / int(_S_word_bit) ? __asize * int(_S_word_bit) : __isize);
}
//Generell ungefähr den Maxwert vom Typ, außer der Allokator kann weniger Byte als für soviel Bit nötig wären.

push_back(bool __x)
{
    if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
        *this->_M_impl._M_finish++ = __x;
    else
        _M_insert_aux(end(), __x);
}
//Wenn noch genug Speicher reserviert, dann eben direkt rein, sonst die Aux-Funktion

	template<typename _Tp, typename _Alloc>
	template<typename... _Args>
	void
	vector<_Tp, _Alloc>::
	_M_insert_aux(iterator __position, _Args&&... __args)
#else
	template<typename _Tp, typename _Alloc>
	void
	vector<_Tp, _Alloc>::
	_M_insert_aux(iterator __position, const _Tp& __x)
#endif
{
	if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
	{
		_Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
		_GLIBCXX_MOVE(*(this->_M_impl._M_finish
		- 1)));
		++this->_M_impl._M_finish;
		#if __cplusplus < 201103L
		_Tp __x_copy = __x;
		#endif
		_GLIBCXX_MOVE_BACKWARD3(__position.base(),
		this->_M_impl._M_finish - 2,
		this->_M_impl._M_finish - 1);
		#if __cplusplus < 201103L
		*__position = __x_copy;
		#else
		*__position = _Tp(std::forward<_Args>(__args)...);
		#endif
	}
	else
	{
		const size_type __len =
		_M_check_len(size_type(1), "vector::_M_insert_aux");
		const size_type __elems_before = __position - begin();
		pointer __new_start(this->_M_allocate(__len));
		pointer __new_finish(__new_start);
		__try
		{
			// The order of the three operations is dictated by the C++0x
			// case, where the moves could alter a new element belonging
			// to the existing vector.  This is an issue only for callers
			// taking the element by const lvalue ref (see 23.1/13).
			_Alloc_traits::construct(this->_M_impl,
			__new_start + __elems_before,
			#if __cplusplus >= 201103L
			std::forward<_Args>(__args)...);
			#else
			__x);
			#endif
			__new_finish = 0;

			__new_finish
			= std::__uninitialized_move_if_noexcept_a
			(this->_M_impl._M_start, __position.base(),
			__new_start, _M_get_Tp_allocator());

			++__new_finish;

			__new_finish
			= std::__uninitialized_move_if_noexcept_a
			(__position.base(), this->_M_impl._M_finish,
			__new_finish, _M_get_Tp_allocator());
		}
		__catch(...)
		{
			if (!__new_finish)
			_Alloc_traits::destroy(this->_M_impl,
			__new_start + __elems_before);
			else
			std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
			_M_deallocate(__new_start, __len);
			__throw_exception_again;
		}
		std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
		_M_get_Tp_allocator());
		_M_deallocate(this->_M_impl._M_start,
		this->_M_impl._M_end_of_storage
		- this->_M_impl._M_start);
		this->_M_impl._M_start = __new_start;
		this->_M_impl._M_finish = __new_finish;
		this->_M_impl._M_end_of_storage = __new_start + __len;
	}
}
//Man beachte das _M_check_len

size_type _M_check_len(size_type __n, const char* __s) const
{
	if (max_size() - size() < __n)
	__throw_length_error(__N(__s));

	const size_type __len = size() + std::max(size(), __n);
	return (__len < size() || __len > max_size()) ? max_size() : __len;
}
//Berücksichtigt also das eigene max_size
https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01501_source.html
https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01593_source.html

Zusammenfassung, die Implementierung prüft auf Überschreiten der max. Größe, Problem gelöst.

...

max_size könnte, bei passend größerem size_type, ohne Probleme 8 (CHAR_BIT) mal den Maxwert von size_t erlauben. Darüber wäre die Beschränkung, dass der allokierte Speicher max. size_t Byte haben kann, hindernd. Vector könnte zwar so implementiert sein, dass ggf. mehr als ein Array gehalten wird (bzw. ein Array von Pointern zu Unterarrays, die alle bis zu size_t groß sein könnten (nur theoretisch, so viel Speicher muss man erst mal haben)), aber dann wäre zB. data() nicht mehr implementierbar und die Implementierung deswegen falsch.
(Vector<bool> in G++ ist insofern sowieso verbuggt, es hat keine funktionierende data.Implementierung. Wie auch? Auch die Bitreferenzobjekt-Sache passt mit manchen Vector-Vorschriften nicht zusammen.)
 
Hi

Im eigentlichen Standard ist size_t (falls ich auf die Schnelle nichts übersehen habe) gar nicht speziell definiert, außer "nebenbei" dass es eben für Parameter von new, Returnwerte von sizeof usw. verwendet wird, größere Objekte illformed sind usw.
Mag sein, aber die Verwendung in allen grösseren Datei- und Memory-Operationen lässt den Schluss zu, dass es oft die unsigned Registergrösse eines Prozessors ist, i.e. so gross wie einfach möglich. Das in Zusammenhang mit der Tatsache, dass size_t als Schleifeniteratortyp oft und gerne verwendet wird, lässt darauf schliessen, dass es "möglichst gross" sein soll.

Das ist natürlich nicht gleichwertig zu einem Standard.
Die (aktuelle/maximale) Anzahl der indizierbaren Elemente eines Vectors (also size und max_size) haben den Typ vector<...>::size_type, nicht size_t.
:confused: Und wofür steht das 't' bei "size_t"?



aber dann wäre zB. data() nicht mehr implementierbar und die Implementierung deswegen falsch.
Im Allgemeinen stimmt das. Im Speziellen könnte man einen kohärenten Speicherbereich in verschiedene Teile à max(size_t) Elemente einteilen. Allerdings: Auf einem 32bit-System hätte man selbst mit PAE Probleme, 2^32 Bits an freiem Speicher zu finden, wenn man gleichzeitig noch ein Programm (und evtl. die C++-Runtime) geladen haben muss. Auf grösseren Systemen wird dieses Problem erst dann relevant, wenn man wirklich viele Informationen speichern muss.

(Vector<bool> in G++ ist insofern sowieso verbuggt, es hat keine funktionierende data.Implementierung. Wie auch? Auch die Bitreferenzobjekt-Sache passt mit manchen Vector-Vorschriften nicht zusammen.)
Wieso nicht? Einfach die Rohdaten zu liefern geht ja - irgendwo werden die bits ja auch gespeichert. Probleme gibt es nur dann, wenn size() % 8 != 0 gilt, aber ein ähnliches Problem hat man ja bei jedem Vektor. Falls du die Bitorder meinst: Da kann man sich bei normalen Vektoren ja auch nicht sicher sein. Oder garantiert der Standard eine spezielle Speicherung?


Gruss
cwriter
 
Und wofür steht das 't' bei "size_t"?
Naja, vermutlich type, aber trotzdem ist std::size_t nicht unbedingt std::vector<x,y>::size_type

kohärenten Speicherbereich
Wenn man nur die Möglichkeit hätte, seine Wunschadresse beim Allokieren anzugeben...

Wieso nicht? Einfach die Rohdaten zu liefern geht ja
Sicher, aber das ist bei G++'s Sonderimplementierung eben ein Array aus unsigned longs mit iA. 8 Bit/Vektorelementen pro Byte, kein Array aus bools mit einem Wert pro Byte. (Einfach casten hilft da natürlich auch nicht).

garantiert der Standard eine spezielle Speicherung?
Intern nicht, aber data muss eben einen rohen Pointer für ein Array des Typs (hier eben bool) liefern. Schwer machbar, wenn man das intern nicht hat und nicht für jeden data-Aufruf eine Kopie anlegen will (und nebenbei noch ein Memoryleak erzeugt)
 
Naja, vermutlich type, aber trotzdem ist std::size_t nicht unbedingt std::vector<x,y>::size_type
Das hatte ich verstanden :)
Es ist eher eine Ungenauigkeit der STL: Der Sinn von size_t war ja gerade, unsigned int abzulösen, um beim Wechsel von 32 auf 64 Bit nicht unnötige Einschränkungen zu übernehmen (sehr vereinfacht gesagt). Es ist der "Grössentyp". Ob's da wirklich noch eine Unterscheidung braucht? Und gibt es überhaupt Implementierungen, wo size_type nicht size_t ist? Die Überlegung ist hier folgende: Annahme, size_type > size_t ist ökonomisch (also der zusätzliche Aufwand hält sich in Grenzen). Dann wäre es sinnvoll, size_t auf size_type zu setzen, denn der Zusatzaufwand ist ja minimal und der Nutzen gross.
Ist hingegen size_t > size_type, dann stellt sich dieselbe Frage umgekehrt: Wenn size_t optimal gross ist, warum dann size_type kleiner halten? (Der einzige Grund hier: max_size() <= size_type^(0.5) (oder max_size() passt anderweitig in eine kleinere Registergrösse), aber da size_t Bytes an einem Block allokiert werden können, sollte sich max_size() nicht so immens weit unter size_t befinden).

Wenn man nur die Möglichkeit hätte, seine Wunschadresse beim Allokieren anzugeben...
Naja, die Runtime darf ja betriebssystemabhängig sein und diese wiederum dürfen alle möglichen Funktionen bereitstellen... Im Standard geht das tatsächlich nicht direkt.

Sicher, aber das ist bei G++'s Sonderimplementierung eben ein Array aus unsigned longs mit iA. 8 Bit/Vektorelementen pro Byte, kein Array aus bools mit einem Wert pro Byte. (Einfach casten hilft da natürlich auch nicht).
Das ist ja auch irgendwie der Witz der Spezialisierung. Dass es nicht so einfach auszulesen ist, ist natürlich doof. Aber 8 Bits für die Speicherung eines einzelnen dualen Zustands zu verbrauchen, ist dann doch Overkill. Oder anders ausgedrückt: Als "Datengrab" ist der std::vector<bool> gut geeignet, als Stack hingegen nicht wirklich.
Und das bisschen Bitmasken geht gerade noch so (auch wenn da wieder Plattformabhängigkeiten auftauchen).

Intern nicht, aber data muss eben einen rohen Pointer für ein Array des Typs (hier eben bool) liefern. Schwer machbar, wenn man das intern nicht hat und nicht für jeden data-Aufruf eine Kopie anlegen will (und nebenbei noch ein Memoryleak erzeugt)
Ach so... Jetzt habe ich es verstanden.

http://en.cppreference.com/w/cpp/container/vector/data
Returns pointer to the underlying array serving as element storage. The pointer is such that range [data(); data() + size()) is always a valid range, even if the container is empty (data() is not dereferenceable in that case).

http://www.cplusplus.com/reference/vector/vector/data/
A pointer to the first element in the array used internally by the vector.
If the vector object is const-qualified, the function returns a pointer to const value_type. Otherwise, it returns a pointer to value_type.
Member type value_type is the type of the elements in the container, defined in vector as an alias of the first class template parameter (T).

Hier sind beide Quellen ein bisschen daneben (oder es ist nur vector<bool> :) ), aber es steht nicht, wie die Daten formatiert sein müssen.
data muss eben einen rohen Pointer für ein Array des Typs (hier eben bool) liefern. Schwer machbar, wenn man das intern nicht hat
Naja, der syntaktische Typ wird ja geliefert. Oder wird direkte Verwendbarkeit auch definiert? Mit fröhlichem Casting kann man die Werte ja wiederbekommen. data() kann ja irgendeinen Pointertyp zurückgeben. Das Iterieren wird dann ein bisschen unschön, aber man kann das data() zuerst auf z.B. char* umcasten und dann bitwise darin rumwuseln (wobei das wenig Sinn macht, da vector ja den []-Operator zur Verfügung stellt). Einzig für SIMD oder zum Kopieren wäre es praktisch, die Daten roh zu haben, und dann weiss man hoffentlich selbst am besten, was zu tun ist.

Ich halte die Spezialisierung des Vektors für nicht katastrophal. Es ist schlicht anwendungsspezifisch. Wenn man die bools direkt haben will, kann man vector<char> verwenden. Wenn man Speicherplatz sparen will, dann nutzt man vector<bool>. Keines der beiden ist besser, keines der beiden kann mehr Elemente halten als das andere.

Gruss
cwriter
 
Und gibt es überhaupt Implementierungen, wo size_type nicht size_t ist?
Keine Ahnung :D

Das ist ja auch irgendwie der Witz der Spezialisierung. Dass es nicht so einfach auszulesen ist, ist natürlich doof. Aber 8 Bits für die Speicherung eines einzelnen dualen Zustands zu verbrauchen, ist dann doch Overkill.
Natürlich, zum Speichersapren etc. ist es toll. Das Problem ist nur, dass es eben kein Vector so wie die anderen ist. Wenn man irgendeine Templateklasse<T> schreibt, und drin vector<T> verwendet, kann man sich "eigentlich" drauf verlassen, dass data() ein ganz normales T-Array ergibt, dass [ i ] eine Referenz auf T ist (und kein Objekt irgendeiner Klasse), usw.usw. Nur bei bool geht dann plötzlich alles daneben.

Imho wäre eine separate Klasse std::bitvector schön gewesen, und vector<bool> einfach so lassen wie es ist.

Hier sind beide Quellen ein bisschen daneben (oder es ist nur vector<bool> :) ), aber es steht nicht, wie die Daten formatiert sein müssen.
23.3.6.4 vector data [vector.data]
T* data() noexcept;
const T* data() const noexcept;

Returns: A pointer such that [data(),data() + size()) is a valid range. For a non-empty vector, data() == &front()

Complexity: Constant time.
(und weiter oben steht dass vector zusammenhängend ist).
Also, ein bool-Pointer, und für einen vector<bool> v müssen v.data()[0] bis v.data()[v.size()-1] gültige bools sein. Sagt für mich eigentlich genug aus. Man hat eben nur ein Achtel Länge, außerdem UB wegen den Werten in den Bytes der "bools" und Verletzung vom Strict Aliasing
:cool: :p

...
letztendlich hab ich wie gesagt nichts gegen eine solche Klasse, nur bitte nicht vector nennen. Templatezeug, und allgemeines Fehlerrisiko (gibt genug Leute, die die Eigenheiten von vector<bool> gar nicht kennen).

Und ganz egal ob gut oder schlecht, sie schaffen es ja anscheinend im Standard nicht mal, das konsistent zu haben (bei anderen Bedingungen gibt es Ausnahmen für bool, bei der zitierten nicht)
 
Zuletzt bearbeitet:
Hallo,

Hi

Erstens, bitte nicht auf cplusplus.com verlassen. Das ist a) nichts offizielles und b) nachweislich voll mit Fehlern.
Oha! Das hatte ich so gar nicht auf dem Schirm. Danke für die Info! Das ist aber ziemlich doof, wenn ich bei Google schnell etwas nachschlagen möchte, und dann z.B. "std::vector<bool> reference" eingebe, wird cplusplus.com bei mir ganz oben eingerankt. Erst der dritte bis vierte Eintrag ist dann von cppreference.com :(.

Imho wäre eine separate Klasse std::bitvector schön gewesen, und vector<bool> einfach so lassen wie es ist.
Die Idee finde ich richtig super :D. Das macht klar, dass diese Klasse gewisse Eigenheiten hat. Außerdem würde es den "normalen" Programmierern die Möglichkeit geben, mit std::vector<bool> einen performanten Container für Wahrheitswerte zu benutzen ohne tieferliegende Bit-Tricksereien.

Wenn ich dich richtig verstehe, ist deine Sorge, dass bei grossen std::vector<bool> size_t einen Overflow hat, bevor er die letzten Elemente erreicht?
Nene nicht wirklich. Ich wünschte ich hätte so viel Hauptspeicher :D. Mein Codeschnipsel operiert auf einem 64 Bit System mit ein paar Hundert Zustandsvektoren, die etwa ein bis fünf Milliarden binäre Zustände speichern müssen. Damit der RAM vom Unirechner nicht unnötig zugekleistert wird, habe ich vector<bool> benutzt. Als statische Alternative gäbe es ja noch std::bitset, allerdings muss man da aufpassen, weil die maximale Stackgröße überschritten würde. Außerdem ändert sich bei der zugrunde liegenden Arithmetik schnell mal die Größe dieser Zustandsvektoren um das zwei- bis dreifache (oder verkleinert sich entsprechend). Deshalb schien mir std::vector<bool> eigentlich perfekt für den Job. Gäbe es ein std::bitvector, hätte ich aber das benutzt :).

Ich finde es schade, dass der Standard da ein wenig schwammig ist. Wer weiß, vielleicht überrascht uns das Kommitee ja noch in C++17.

Theoretisch wäre es natürlich auch möglich gewesen eine eigene Klasse zu schreiben, die sich um die Bitverschiebungen etc. kümmert. Aber ich bin zu faul :p.
Gibt es denn vielleicht sogar schon Bibliotheken, die ein dynamisches Bitset bereitstellen?

Gruß Technipion
 
Gibt es denn vielleicht sogar schon Bibliotheken, die ein dynamisches Bitset bereitstellen?
Wie immer: http://www.boost.org/doc/libs/1_36_0/libs/dynamic_bitset/dynamic_bitset.html

Boost ist schon recht krass... Das Teil hat echt alles, was man sich vorstellen kann :)

Außerdem ändert sich bei der zugrunde liegenden Arithmetik schnell mal die Größe dieser Zustandsvektoren um das zwei- bis dreifache (oder verkleinert sich entsprechend). Deshalb schien mir std::vector<bool> eigentlich perfekt für den Job. Gäbe es ein std::bitvector, hätte ich aber das benutzt :).
Vektoren sind eigentlich auch nicht wirklich gut für häufige Grössenänderungen... Sicher, es ist einfach zu nutzen, aber nicht wirklich gut für die Performance, wenn oft Grössenänderungen um die Verdoppelung herum passieren.
Ich finde es schade, dass der Standard da ein wenig schwammig ist. Wer weiß, vielleicht überrascht uns das Kommitee ja noch in C++17.
http://softwareengineering.stackexchange.com/a/335771
Herb Sutter hat gesagt.:
The vector specialization was intentionally put into the standard to provide an example of how to write a proxied container. A "proxied container" is a container whose objects you don't get at directly; instead of giving you pointers or references to a contained object, a proxied container gives you proxy objects that can be used to indirectly access or manipulate a contained object. Proxied collections can be useful in cases where the objects within the collection cannot always be reliably accessed directly as though they were in memory, as for example with a disk-based collection that automatically pages pieces of itself in and out of memory under the covers as needed. So the idea was to show how to make such a proxied collection meet the requirements of a "container" in the sense defined by the standard library.
Vielleicht - allerdings würde das Inkompatibilitäten einführen - ich glaube nicht, dass das Kommitee am vector rütteln wird.

Gruss
cwriter
 
Hi,
Wie immer: http://www.boost.org/doc/libs/1_36_0/libs/dynamic_bitset/dynamic_bitset.html

Boost ist schon recht krass... Das Teil hat echt alles, was man sich vorstellen kann :)
Da hätte ich ja drauf kommen können :D. Boost ist so umfangreich, dass man gar nicht alle Module davon kennen kann...

Über den Post war ich auch schon gestoßen. Naja, die Idee hat ja etwas, allerdings finde ich die STL nicht unbedingt genial als Vorlage geeignet. Ich habe mir gerade mal die Files für die Implementierung von vector<bool> angeschaut, und die haben mich etwas erschlagen :oops:.

Aber dank Boost habe ich jetzt eine Alternative. Ich werde die entsprechenden Stellen in meinem Code mal umschreiben, falls es einen enormen Geschwindigkeitsvorteil bringt, sag ich Bescheid. Ansonsten ist meine Frage zufriedenstellend beantwortet worden. Danke euch :).

Gruß Technipion
 
Zurück