<?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[Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt;]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>eigentlich sind sich boost::ptr_vector und std::vector ja ziemlich ähnlich.<br />
Deswegen würde ich gerne eine Template-Funktion schreiben, die mit beiden umgehen kann. Bevor ich jetzt anfange irgendwelche Wrapper-Klassen zu schreiben, die den operator-&gt;() zur Verfügung stellen, frag ich hier mal, ob es eine einfache Lösung (mit Hilfe von boost?) gibt.</p>
<p>Folgender Code liefert ja verständlicherweise unterschiedliche Ergebnisse.</p>
<pre><code class="language-cpp">#include &lt;boost/ptr_container/ptr_vector.hpp&gt;
#include &lt;iostream&gt;

template&lt;typename TList&gt;
void print(const TList&amp; list){
        for(typename TList::const_iterator it = list.begin(); it != list.end(); ++it){
                std::cout &lt;&lt; *it &lt;&lt; std::endl;
        }
/*      for(typename TList::const_reference e : list){
                std::cout &lt;&lt; e &lt;&lt; std::endl;
        }*/
}

int main(){
        boost::ptr_vector&lt;int&gt; bvec;
        bvec.push_back(new int(1));
        bvec.push_back(new int(2));
        bvec.push_back(new int(3));
        print(bvec);
        std::vector&lt;int*&gt; svec;
        svec.push_back(new int(1));
        svec.push_back(new int(2));
        svec.push_back(new int(3));
        print(svec);
}
</code></pre>
<blockquote>
<p>1<br />
2<br />
3<br />
0x1002000b0<br />
0x1002000f0<br />
0x1002000e0</p>
</blockquote>
<p>Einmal iteriert er halt über die Referenzen, beim anderen mal über Zaiger.</p>
<p>Der Code kann gerne wie ihr seht auch C++0x Features enthalten.<br />
Wie würdet ihr das lösen?</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/284803/template-function-für-boost-ptr_vector-lt-foo-gt-und-std-vector-lt-foo-gt</link><generator>RSS for Node</generator><lastBuildDate>Fri, 21 Aug 2026 18:20:15 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/284803.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 08 Apr 2011 11:53:26 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 11:53:26 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>eigentlich sind sich boost::ptr_vector und std::vector ja ziemlich ähnlich.<br />
Deswegen würde ich gerne eine Template-Funktion schreiben, die mit beiden umgehen kann. Bevor ich jetzt anfange irgendwelche Wrapper-Klassen zu schreiben, die den operator-&gt;() zur Verfügung stellen, frag ich hier mal, ob es eine einfache Lösung (mit Hilfe von boost?) gibt.</p>
<p>Folgender Code liefert ja verständlicherweise unterschiedliche Ergebnisse.</p>
<pre><code class="language-cpp">#include &lt;boost/ptr_container/ptr_vector.hpp&gt;
#include &lt;iostream&gt;

template&lt;typename TList&gt;
void print(const TList&amp; list){
        for(typename TList::const_iterator it = list.begin(); it != list.end(); ++it){
                std::cout &lt;&lt; *it &lt;&lt; std::endl;
        }
/*      for(typename TList::const_reference e : list){
                std::cout &lt;&lt; e &lt;&lt; std::endl;
        }*/
}

int main(){
        boost::ptr_vector&lt;int&gt; bvec;
        bvec.push_back(new int(1));
        bvec.push_back(new int(2));
        bvec.push_back(new int(3));
        print(bvec);
        std::vector&lt;int*&gt; svec;
        svec.push_back(new int(1));
        svec.push_back(new int(2));
        svec.push_back(new int(3));
        print(svec);
}
</code></pre>
<blockquote>
<p>1<br />
2<br />
3<br />
0x1002000b0<br />
0x1002000f0<br />
0x1002000e0</p>
</blockquote>
<p>Einmal iteriert er halt über die Referenzen, beim anderen mal über Zaiger.</p>
<p>Der Code kann gerne wie ihr seht auch C++0x Features enthalten.<br />
Wie würdet ihr das lösen?</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046335</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046335</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 08 Apr 2011 11:53:26 GMT</pubDate></item><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 12:13:49 GMT]]></title><description><![CDATA[<p>Was willst du erreichen? Wieso speicherst du in dem normalen vector Pointer? Der Sinn der Pointer-Container ist doch gerade, dass du in ihnen Pointer speichern kannst, die sich dann wie normale Werte verhalten. Und dann könntest du beide Container äquivalent benutzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046350</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046350</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 08 Apr 2011 12:13:49 GMT</pubDate></item><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 12:14:02 GMT]]></title><description><![CDATA[<p>Ich würde Funktionsüberladung nehmen, zumindest bei diesem Beispiel. Dinge wie <code>is_pointer</code> , SFINAE und sonstige Metaprogrammierung fände ich hier übertrieben.</p>
<p>Übrigens hast du Memory Leaks <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046351</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046351</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 08 Apr 2011 12:14:02 GMT</pubDate></item><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 12:32:06 GMT]]></title><description><![CDATA[<p>So könnte man das übrigens machen (Memory leaks korrigiere ich jetzt mal nicht). Ich finde das Vorhaben aber trotzdem komisch.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;boost/ptr_container/ptr_vector.hpp&gt;

using namespace std;

template &lt;typename T, typename value_type&gt; struct print_impl
{
  void operator()(const T&amp; t)
  {
    cout&lt;&lt;&quot;Pointer Container&quot;&lt;&lt;endl;
    for(typename T::const_iterator it = t.begin(); it != t.end(); ++it){
      std::cout &lt;&lt; *it &lt;&lt; std::endl;
    }
  }
};

template &lt;typename T, typename value_type&gt; struct print_impl&lt;T, value_type *&gt;
{
  void operator()(const T&amp; t)
  {
    cout&lt;&lt;&quot;Normaler Container mit Pointern&quot;&lt;&lt;endl;
    for(typename T::const_iterator it = t.begin(); it != t.end(); ++it){
      std::cout &lt;&lt; **it &lt;&lt; std::endl;
    }
  }
};

template &lt;typename T&gt; void print(const T&amp; t)
{
  print_impl&lt;T, typename T::iterator::value_type&gt;()(t);
}

int main()
{
        boost::ptr_vector&lt;int&gt; bvec;
        bvec.push_back(new int(1));
        bvec.push_back(new int(2));
        bvec.push_back(new int(3));
        std::vector&lt;int*&gt; svec;
        svec.push_back(new int(1));
        svec.push_back(new int(2));
        svec.push_back(new int(3));

        print(bvec);
        print(svec);

}
</code></pre>
<p>edit: Das geht natürlich nur so lange gut, wie du nicht Pointer auf Pointer oder höhere Indirektionen hast.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046361</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046361</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 08 Apr 2011 12:32:06 GMT</pubDate></item><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 13:00:49 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Wieso speicherst du in dem normalen vector Pointer?</p>
</blockquote>
<p>Bitte korrigier mich, aber einen ptr_vector kann ich doch nur verwenden, wenn er auch den Besitz des Zeigers kriegt, oder?</p>
<p>Nexus schrieb:</p>
<blockquote>
<p>Übrigens hast du Memory Leaks <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Ich weiß <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /><br />
Wollte halt nur soviel Code hier posten, dass er kompilierbar ist <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Bezüglich Funktionsüberladung/Templatespezialisierung:<br />
Ich dachte jetzt eigentlich an den Fall, dass man einen komplexen Algorithmus ausführen möchte. Bei Funktionsüberladung müsste ich alles 2mal implementieren.</p>
<p>Angenommen ich habe einen ptr_vector und möchte den geringsten Unterschied zwischen zwei Elementen (wie auch immer definiert) ermitteln. Dann möchte ich auf einer Teilmenge davon die gleiche Operation ausführen. Was mache ich? Ich speichere mir die Pointer in einem Vektor. Der Besitz bleibt beim ptr_vector, der alle Elemente enthält. Oder?</p>
<p>SeppJ schrieb:</p>
<blockquote>
<p>edit: Das geht natürlich nur so lange gut, wie du nicht Pointer auf Pointer oder höhere Indirektionen hast.</p>
</blockquote>
<p>Dessen bin ich mir bewusst <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
Gut, dass du es erwähnst, aber hast du schonmal einen ptr_vector&lt;Foo*&gt; verwendet?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046370</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046370</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 08 Apr 2011 13:00:49 GMT</pubDate></item><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 14:55:53 GMT]]></title><description><![CDATA[<p>XSpille schrieb:</p>
<blockquote>
<p>Hallo zusammen,</p>
<p>eigentlich sind sich boost::ptr_vector und std::vector ja ziemlich ähnlich.<br />
Deswegen würde ich gerne eine Template-Funktion schreiben, die mit beiden umgehen kann.</p>
</blockquote>
<p>Das halte ich nicht für sinnvoll. Die Template-Funktion selbst sollte IMO nicht angepasst werden. T und T* sind halt nicht dasselbe. Ein Template zu schreiben das T und T* gleich behandelt ist daher IMO auch Quatsch. Was wenn T=int*, wie willst du das behandeln?</p>
<p>D.h. du solltest das dort regeln, wo das Template aufgerufen wird.</p>
<blockquote>
<p>Bevor ich jetzt anfange irgendwelche Wrapper-Klassen zu schreiben, die den operator-&gt;() zur Verfügung stellen, frag ich hier mal, ob es eine einfache Lösung (mit Hilfe von boost?) gibt.</p>
</blockquote>
<p>Es gibt Boost.Lambda, damit kannst du &quot;in place&quot; einen Funktor erstellen der den übergebenen Parameter dereferenziert und an einen anderen Funktor weitergibt.</p>
<p>Oder du kannst <code>boost::make_indirect_iterator(base)</code> verwenden um einen Iterator zu basteln der beim Dereferenzieren <code>**base</code> zurückgibt (also den übergebenen Iterator einmal zusätzlich dereferenziert).</p>
<p>Findest du z.B. hier schön beschrieben:<br />
<a href="http://stackoverflow.com/questions/5437347/using-stl-algorithms-with-shared-ptr-function-objects/5440461#5440461" rel="nofollow">http://stackoverflow.com/questions/5437347/using-stl-algorithms-with-shared-ptr-function-objects/5440461#5440461</a></p>
<p>p.S.: dazu musst du deine &quot;print&quot; Funktion natürlich umbauen. Entweder <code>print(iterator begin, iterator end)</code> , oder einen Funktor <code>print(element const&amp; e)</code> machen, und den dann mit <code>std::foreach</code> aufrufen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046421</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046421</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 08 Apr 2011 14:55:53 GMT</pubDate></item><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 18:38:41 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Das halte ich nicht für sinnvoll. Die Template-Funktion selbst sollte IMO nicht angepasst werden. T und T* sind halt nicht dasselbe. Ein Template zu schreiben das T und T* gleich behandelt ist daher IMO auch Quatsch. Was wenn T=int*, wie willst du das behandeln?</p>
</blockquote>
<p>Ich gebe dir recht, dass eine generelle Gleichbehandlung von T und T* quatsch ist, allerdings sind boost::ptr_vector&lt;Foo&gt; und std::vector&lt;Foo*&gt;, abgesehen von Besitzverhältnissen in meinen Augen ziemlich ähnlich...</p>
<p>Ich werde zukünftig wohl boost::make_indirect_iterator verwenden, falls ein Iterator ausreichend ist:</p>
<pre><code class="language-cpp">#include &lt;boost/ptr_container/ptr_vector.hpp&gt;
#include &lt;iostream&gt;
#include &lt;boost/iterator/indirect_iterator.hpp&gt;
#include &lt;algorithm&gt;

template&lt;typename T&gt;
void print(T begin, T end){
        for(T it = begin; it != end; ++it){
                std::cout &lt;&lt; *it &lt;&lt; std::endl;
        }
}

template&lt;typename T&gt;
void print(const T&amp; t){
        print(t.begin(), t.end());
}

int main(){
        boost::ptr_vector&lt;int&gt; bvec;
        bvec.push_back(new int(1));
        bvec.push_back(new int(2));
        bvec.push_back(new int(3));
        print(bvec);
        std::vector&lt;int*&gt; svec;
        for(int&amp; i : bvec){ svec.push_back(&amp;i); }
        print(boost::make_indirect_iterator(svec.begin()), boost::make_indirect_iterator(svec.end()));
}
</code></pre>
<p>Genau so etwas hab ich gesucht! THX hustbaer</p>
<p>Hier noch eine boost-lambda-Version:</p>
<pre><code class="language-cpp">#include &lt;boost/ptr_container/ptr_vector.hpp&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;
#include &lt;boost/lambda/lambda.hpp&gt;
#include &lt;boost/lambda/bind.hpp&gt;

void print_element(int t){
        std::cout &lt;&lt; t &lt;&lt; std::endl;
}

template&lt;typename T&gt;
void print(const T&amp; t){
        std::for_each(t.begin(), t.end(), &amp;print_element);
}

template&lt;typename T&gt;
void print_pointer(const T&amp; t){
        std::for_each(t.begin(), t.end(), boost::lambda::bind(print_element, *boost::lambda::_1));

}
int main(){
        boost::ptr_vector&lt;int&gt; bvec;
        bvec.push_back(new int(1));
        bvec.push_back(new int(2));
        bvec.push_back(new int(3));
        print(bvec);
        std::vector&lt;int*&gt; svec;
        for(int&amp; i : bvec){ svec.push_back(&amp;i); }
        print_pointer(svec);
}
</code></pre>
<p>DANKE EUCH ALLEN <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><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/12954">@Nexus</a>: Diesmal extra für dich ohne memory leaks <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046502</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046502</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 08 Apr 2011 18:38:41 GMT</pubDate></item><item><title><![CDATA[Reply to Template function für boost::ptr_vector&amp;lt;Foo&amp;gt; und std::vector&amp;lt;Foo*&amp;gt; on Fri, 08 Apr 2011 18:47:55 GMT]]></title><description><![CDATA[<p>Eine Nachfrage noch:</p>
<p>Brauch ich in folgendem Fall wirklich boost::remove_pointer?</p>
<pre><code class="language-cpp">#include &lt;boost/ptr_container/ptr_vector.hpp&gt;
#include &lt;iostream&gt;
#include &lt;algorithm&gt;

template&lt;typename T&gt;
void print_element(const T&amp; t){
        std::cout &lt;&lt; t &lt;&lt; std::endl;
}

template&lt;typename T&gt;
void print(const T&amp; t){
        std::for_each(t.begin(), t.end(), &amp;print_element&lt;typename boost::remove_pointer&lt;typename T::value_type&gt;::type&gt;);
}

int main(){
        boost::ptr_vector&lt;int&gt; bvec;
        bvec.push_back(new int(1));
        bvec.push_back(new int(2));
        bvec.push_back(new int(3));
        print(bvec);
}
</code></pre>
<p>Gibt es keinen typedef für den eigentlichen Template-Parameter?<br />
(Wahrscheinlich schon <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /> )</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2046507</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2046507</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 08 Apr 2011 18:47:55 GMT</pubDate></item></channel></rss>