<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[vector wrapper für eigenen Container - So Ok?]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich wollte vor kurzem einen eigenen Container erstellen, der seine Werte intern in einem <code>std::vector&lt;T&gt;</code> speichert und managed. Das hat auch sehr gut funktioniert, bis ich irgendwann mal einen <code>container&lt;bool&gt;</code> erstellen wollte. Nach einiger Recherche was da schief läuft bin ich darauf gestoßen dass <code>vector&lt;bool&gt;</code> eine Spezialisierung von <code>std::vector</code> ist, und keine Rückgabe von Referenzen erlaubt (da die Werte hier als einzelne Bits gespeichert werden und solche ja nicht addressierbar sind).</p>
<p>Da ich für meinen Container aber nach außen hin ein konsistentes Interface bereitstellen will, habe ich einen Wrapper für <code>std::vector</code> geschrieben:</p>
<pre><code>template &lt;class T&gt;
struct vector_wrapper
{
	vector_wrapper(size_t size_) { values.resize(size_); };
	void set(size_t index_, T const &amp;value_) { values[index_] = value_; };
	T &amp;get(size_t index_) { return values[index_]; };
	T const &amp;get(size_t index_) const { return values[index_]; };

	std::vector&lt;T&gt; values;
};

template &lt;&gt;
struct vector_wrapper&lt;bool&gt;
{
	vector_wrapper(size_t size_) { values.resize(size_); };
	void set(size_t index_, bool value_) { values[index_] = !!value_; };
	bool &amp;get(size_t index_) { return reinterpret_cast&lt;bool &amp;&gt;(values[index_]); };
	bool const &amp;get(size_t index_) const { return reinterpret_cast&lt;bool const &amp;&gt;(values[index_]); };

	std::vector&lt;char&gt; values;
};

template &lt;class T&gt;
class container
{
	public:	
		container(size_t size_) : values(size_) {};
		void set(size_t index_, T const &amp; value_) { values.set(index_, value_); };
		T &amp;get(size_t index_) { return values.get(index_); };
		T const &amp;get(size_t index_) const { return values.get(index_); };

	private:
		vector_wrapper&lt;T&gt; values;
};
</code></pre>
<p>Dazu hab ich jetzt ein paar Fragen: Ist das Ganze so Ok oder gibt es einen noch besseren Weg? Casts sagt man ja allgemein nach dass sie böse sind, in diesem Fall auch? Ich sehe nämlich keine möglichkeit das ohne Cast hier zu lösen. Und, gibt es Fälle in denen dieser Ansatz failen könnte?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/325794/vector-wrapper-für-eigenen-container-so-ok</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Jul 2026 23:00:38 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/325794.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 18 May 2014 18:36:48 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 18:36:48 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich wollte vor kurzem einen eigenen Container erstellen, der seine Werte intern in einem <code>std::vector&lt;T&gt;</code> speichert und managed. Das hat auch sehr gut funktioniert, bis ich irgendwann mal einen <code>container&lt;bool&gt;</code> erstellen wollte. Nach einiger Recherche was da schief läuft bin ich darauf gestoßen dass <code>vector&lt;bool&gt;</code> eine Spezialisierung von <code>std::vector</code> ist, und keine Rückgabe von Referenzen erlaubt (da die Werte hier als einzelne Bits gespeichert werden und solche ja nicht addressierbar sind).</p>
<p>Da ich für meinen Container aber nach außen hin ein konsistentes Interface bereitstellen will, habe ich einen Wrapper für <code>std::vector</code> geschrieben:</p>
<pre><code>template &lt;class T&gt;
struct vector_wrapper
{
	vector_wrapper(size_t size_) { values.resize(size_); };
	void set(size_t index_, T const &amp;value_) { values[index_] = value_; };
	T &amp;get(size_t index_) { return values[index_]; };
	T const &amp;get(size_t index_) const { return values[index_]; };

	std::vector&lt;T&gt; values;
};

template &lt;&gt;
struct vector_wrapper&lt;bool&gt;
{
	vector_wrapper(size_t size_) { values.resize(size_); };
	void set(size_t index_, bool value_) { values[index_] = !!value_; };
	bool &amp;get(size_t index_) { return reinterpret_cast&lt;bool &amp;&gt;(values[index_]); };
	bool const &amp;get(size_t index_) const { return reinterpret_cast&lt;bool const &amp;&gt;(values[index_]); };

	std::vector&lt;char&gt; values;
};

template &lt;class T&gt;
class container
{
	public:	
		container(size_t size_) : values(size_) {};
		void set(size_t index_, T const &amp; value_) { values.set(index_, value_); };
		T &amp;get(size_t index_) { return values.get(index_); };
		T const &amp;get(size_t index_) const { return values.get(index_); };

	private:
		vector_wrapper&lt;T&gt; values;
};
</code></pre>
<p>Dazu hab ich jetzt ein paar Fragen: Ist das Ganze so Ok oder gibt es einen noch besseren Weg? Casts sagt man ja allgemein nach dass sie böse sind, in diesem Fall auch? Ich sehe nämlich keine möglichkeit das ohne Cast hier zu lösen. Und, gibt es Fälle in denen dieser Ansatz failen könnte?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399772</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399772</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sun, 18 May 2014 18:36:48 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 18:41:30 GMT]]></title><description><![CDATA[<p>happystudent schrieb:</p>
<blockquote>
<p>Ist das Ganze so Ok</p>
</blockquote>
<p>Nein, reinterpret_cast ist böse und lässt sich hier vermeiden.</p>
<pre><code class="language-cpp">struct bool_wrapper {
  bool value;
  operator bool&amp;() { return value; }
  operator bool const&amp;() const { return value; }
};

template &lt;class T&gt;
struct vector_wrapper
{
    vector_wrapper(size_t size_) { values.resize(size_); };
    void set(size_t index_, T const &amp;value_) { values[index_] = value_; };
    T &amp;get(size_t index_) { return values[index_]; };
    T const &amp;get(size_t index_) const { return values[index_]; };

    std::vector&lt;std::conditiona&lt;std::is_same&lt;T,bool&gt;::value,bool_wrapper,T&gt; values;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2399773</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399773</guid><dc:creator><![CDATA[ungetestet]]></dc:creator><pubDate>Sun, 18 May 2014 18:41:30 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 19:18:48 GMT]]></title><description><![CDATA[<p>Hm, also nach ein paar kleinen Korrekturen funktioniert das schonmal für alle nicht-bool Typen:</p>
<pre><code>struct bool_wrapper {
	bool value;
	operator bool&amp;() { return value; }
	operator bool const&amp;() const { return value; }
};

template &lt;class T&gt;
struct vector_wrapper
{
	vector_wrapper(size_t size_) { values.resize(size_); };
	void set(size_t index_, T const &amp;value_) { values[index_] = value_; };
	T &amp;get(size_t index_) { return values[index_]; };
	T const &amp;get(size_t index_) const { return values[index_]; };

	typedef typename std::conditional&lt;std::is_same&lt;T, bool&gt;::value, bool_wrapper, T&gt;::type _T;
	std::vector&lt;_T&gt; values;
};
</code></pre>
<p>Beim Versuch einen vector_wrapper vom Typ bool zu instanziieren erhalte ich aber folgende Fehlermeldung:</p>
<p><strong>error C2679: Binärer Operator '=': Es konnte kein Operator gefunden werden, der einen rechtsseitigen Operanden vom Typ 'const bool' akzeptiert (oder keine geeignete Konvertierung möglich)</strong></p>
<p>Dabei wird auf Zeile 11 (die set-Methode verwiesen).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399781</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399781</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sun, 18 May 2014 19:18:48 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 19:31:01 GMT]]></title><description><![CDATA[<p>Dann füge noch das bei bool_wrapper ein:</p>
<pre><code class="language-cpp">void operator=(bool new_value) { value = new_value; }
</code></pre>
<p>Verstehst du, was meine Idee ist?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399785</guid><dc:creator><![CDATA[ungetestet]]></dc:creator><pubDate>Sun, 18 May 2014 19:31:01 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 19:37:04 GMT]]></title><description><![CDATA[<p>ungetestet schrieb:</p>
<blockquote>
<p>Dann füge noch das bei bool_wrapper ein:</p>
<pre><code class="language-cpp">void operator=(bool new_value) { value = new_value; }
</code></pre>
<p>Verstehst du, was meine Idee ist?</p>
</blockquote>
<p>Ok, alles klar. Ja, ich versteh schon was deine Idee ist, hab das Ganze jetzt so realisiert (ein entsprechender Constructor mit Default-Argument hats auch getan):</p>
<pre><code>template &lt;class T&gt;
class container
{
	public:
		container(size_t size_) { values.resize(size_); };
		void set(size_t index_, T const &amp;value_) { values[index_] = value_; };
		T &amp;get(size_t index_) { return values[index_]; };
		T const &amp;get(size_t index_) const { return values[index_]; };

	private:
		struct bool_wrapper {
			bool_wrapper(bool value_ = false) : value(value_) {};
			bool value;
			operator bool&amp;() { return value; }
			operator bool const&amp;() const { return value; }
		};
		typedef typename std::conditional&lt;std::is_same&lt;T, bool&gt;::value, bool_wrapper, T&gt;::type T_;
		std::vector&lt;T_&gt; values;
};
</code></pre>
<p>Funktioniert wie ne Eins und ist auch noch kürzer als meine Lösung <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
<p>Dann hab ich endlich diese nervige Spezialisierung umgangen, ich frag mich echt was sich die Typen dabei gedacht haben als sie die vector Klasse gemacht haben <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399787</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399787</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sun, 18 May 2014 19:37:04 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 20:07:38 GMT]]></title><description><![CDATA[<pre><code>container(size_t size_) { values.resize(size_); };
</code></pre>
<p>Da sollte <code>explicit</code> hin.</p>
<pre><code>void set(size_t index_, T const &amp;value_) { values[index_] = value_; };
T &amp;get(size_t index_) { return values[index_]; };
</code></pre>
<p>Was soll das <code>set()</code> bringen? Wenn <code>get()</code> eh schon eine Referenz zurückgibt und dir so Schreibzugriff gewährt, kannst du dir die Kapselung gleich sparen. Ganz abgesehen davon, dass <code>operator[]</code> eine intuitivere Syntax ermöglicht.</p>
<p>happystudent schrieb:</p>
<blockquote>
<p>ich frag mich echt was sich die Typen dabei gedacht haben als sie die vector Klasse gemacht haben <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
</blockquote>
<p>Sie wollten <code>vector&lt;bool&gt;</code> als Bitset behandeln und platzspeichernd arbeiten. Dass das nicht immer ideal ist, wurde erst mit der Zeit klar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399796</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399796</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 18 May 2014 20:07:38 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 20:15:41 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Was soll das <code>set()</code> bringen? Wenn <code>get()</code> eh schon eine Referenz zurückgibt und dir so Schreibzugriff gewährt, kannst du dir die Kapselung gleich sparen. Ganz abgesehen davon, dass <code>operator[]</code> eine intuitivere Syntax ermöglicht.</p>
</blockquote>
<p>Jo, das stimmt, das <code>set()</code> ist ziemlich redundant, werd ich wohl durch <code>operator[]</code> ersetzen.</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Sie wollten <code>vector&lt;bool&gt;</code> als Bitset behandeln und platzspeichernd arbeiten. Dass das nicht immer ideal ist, wurde erst mit der Zeit klar.</p>
</blockquote>
<p>Warum wird sowas dann eigentlich nicht gefixt?</p>
<p>Also Spezialisierungen sind ja schön und gut aber ich finde die Funktionaliät nach außen hin sollte sich dadurch nicht verändern... Sonst kann man ja einfach ne neue Klasse machen, die auf Speicher optimiert ist (ka, zum Beispiel <code>bool_vector</code> oder so), würde auf jeden Fall viel Konfusion verhindern <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399799</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399799</guid><dc:creator><![CDATA[happystudent]]></dc:creator><pubDate>Sun, 18 May 2014 20:15:41 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Sun, 18 May 2014 20:21:51 GMT]]></title><description><![CDATA[<p>happystudent schrieb:</p>
<blockquote>
<p>Jo, das stimmt, das <code>set()</code> ist ziemlich redundant, werd ich wohl durch <code>operator[]</code> ersetzen.</p>
</blockquote>
<p><code>get()</code> kannst du auch gleich entfernen.</p>
<p>happystudent schrieb:</p>
<blockquote>
<p>Warum wird sowas dann eigentlich nicht gefixt?</p>
</blockquote>
<p>Weil es bestehenden Code kaputt machen würde.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399802</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399802</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Sun, 18 May 2014 20:21:51 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Mon, 19 May 2014 07:57:30 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>happystudent schrieb:</p>
<blockquote>
<p>Warum wird sowas dann eigentlich nicht gefixt?</p>
</blockquote>
<p>Weil es bestehenden Code kaputt machen würde.</p>
</blockquote>
<p>Gibt es wirklich irgendjemanden, der sich auf das kaputte Verhalten verlassen hat? Oder hast du da ein gutes Beispiel?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399840</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399840</guid><dc:creator><![CDATA[TyRoXx]]></dc:creator><pubDate>Mon, 19 May 2014 07:57:30 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Wed, 11 Jun 2014 22:23:17 GMT]]></title><description><![CDATA[<p>...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399847</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399847</guid><dc:creator><![CDATA[Swordfish]]></dc:creator><pubDate>Wed, 11 Jun 2014 22:23:17 GMT</pubDate></item><item><title><![CDATA[Reply to vector wrapper für eigenen Container - So Ok? on Mon, 19 May 2014 11:15:08 GMT]]></title><description><![CDATA[<blockquote>
<p>Gibt es wirklich irgendjemanden, der sich auf das kaputte Verhalten verlassen hat?</p>
</blockquote>
<p><s>Es ist nicht kaputt, es ist einfach anders.</s> Manchmal bekommt man auch einen gehörigen Performance-Boost. Und das, ohne <code>boost::dynamic_bitset</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2399875</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2399875</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 19 May 2014 11:15:08 GMT</pubDate></item></channel></rss>