<?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[std::set::find-Problem]]></title><description><![CDATA[<p>Halli hallo!<br />
Leider bin ich auf Probleme bei der Anwendung von std::set gestoßen.<br />
Und zwar habe ich verschiedene Objekte mit einem gemeinsamen Interface, welche nur auf dem Heap existieren können und per boost::shared_ptr referenzgezählt werden. Zudem ist allen gemein, dass sie ein Namens-Attribut besitzen (über die gesamte Lebenszeit der Objekt konstant), welches als Schlüssel beim Suchen fungiert. Nun ist ja an sich eine normale Herangehensweise, dass man diese Objekte in eine std::map verfrachtet. Allerdings bedeutet das in meinem Fall, dass ich dieses Vergleichattribut unnötig duplizieren müsste. Also habe ich mir gedacht, ich packe sie in ein std::set mit einem benutzerdefinierten Vergleichs-Objekt. Das funktioniert allerdings nur schön, bis man im set dann mal ein Objekt mit dem zugehörigen Schlüssel suchen muss. Denn leider gibt es bei std::set::find keine Möglichkeit, beispielsweise einen Funktor mitzugeben, der aus dem im set gespeicherten Zeiger den Schlüssel extrahiert und mit einem gegebenen Schlüssel vergleicht. std::find_if hingegen dürfte ja meinem Wissen nach nicht von der bereits sortierten Datenstruktur des sets profitieren.</p>
<p>Also meine Frage: Gibt es irgendwie eine Möglichkeit, die effiziente Suche in einem set so anzupassen, dass das zu vergleichende Objekt nicht vom Typ der im set gespeicherten Objekte sein muss (d.h. dass ich derefenzieren und eine Methode aufrufen kann, um sie kompatibel zu machen).</p>
<p>Viele Grüße,<br />
Michael</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/232973/std-set-find-problem</link><generator>RSS for Node</generator><lastBuildDate>Sat, 04 Apr 2026 21:35:34 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/232973.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 29 Jan 2009 16:20:09 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to std::set::find-Problem on Thu, 29 Jan 2009 16:20:09 GMT]]></title><description><![CDATA[<p>Halli hallo!<br />
Leider bin ich auf Probleme bei der Anwendung von std::set gestoßen.<br />
Und zwar habe ich verschiedene Objekte mit einem gemeinsamen Interface, welche nur auf dem Heap existieren können und per boost::shared_ptr referenzgezählt werden. Zudem ist allen gemein, dass sie ein Namens-Attribut besitzen (über die gesamte Lebenszeit der Objekt konstant), welches als Schlüssel beim Suchen fungiert. Nun ist ja an sich eine normale Herangehensweise, dass man diese Objekte in eine std::map verfrachtet. Allerdings bedeutet das in meinem Fall, dass ich dieses Vergleichattribut unnötig duplizieren müsste. Also habe ich mir gedacht, ich packe sie in ein std::set mit einem benutzerdefinierten Vergleichs-Objekt. Das funktioniert allerdings nur schön, bis man im set dann mal ein Objekt mit dem zugehörigen Schlüssel suchen muss. Denn leider gibt es bei std::set::find keine Möglichkeit, beispielsweise einen Funktor mitzugeben, der aus dem im set gespeicherten Zeiger den Schlüssel extrahiert und mit einem gegebenen Schlüssel vergleicht. std::find_if hingegen dürfte ja meinem Wissen nach nicht von der bereits sortierten Datenstruktur des sets profitieren.</p>
<p>Also meine Frage: Gibt es irgendwie eine Möglichkeit, die effiziente Suche in einem set so anzupassen, dass das zu vergleichende Objekt nicht vom Typ der im set gespeicherten Objekte sein muss (d.h. dass ich derefenzieren und eine Methode aufrufen kann, um sie kompatibel zu machen).</p>
<p>Viele Grüße,<br />
Michael</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1654470</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1654470</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 29 Jan 2009 16:20:09 GMT</pubDate></item><item><title><![CDATA[Reply to std::set::find-Problem on Thu, 29 Jan 2009 16:22:45 GMT]]></title><description><![CDATA[<p>Guck Dir mal den <a href="http://www.cplusplus.com/reference/stl/set/set.html" rel="nofollow">Ctor</a> von std::set an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1654472</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1654472</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Thu, 29 Jan 2009 16:22:45 GMT</pubDate></item><item><title><![CDATA[Reply to std::set::find-Problem on Thu, 29 Jan 2009 16:30:11 GMT]]></title><description><![CDATA[<p>Danke für die rasche Antwort.<br />
Leider ist das ja das Problem. Ich benutze ja bereits dieses benutzerdefinierte Vergleichsobjekt (es dereferenziert die gespeicherten Zeiger, und vergleicht dann die Attribute). Nur hilft mir dass nicht weiter, weil ich bei set::find (oder einer ähnlich effizienten Alternative) ja den Schlüssel mitgeben möchte, und nicht einen Zeiger auf ein Objekt, welches diesen Schlüssel besitzt. Allerdings möchte set::find ein Objekt des gespeicherten Typs haben und es gibt leider keine template-Variante, die einen weiteren (verschiedenen) Funktor akzeptiert.</p>
<p>Viele Grüße,<br />
Michael</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1654475</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1654475</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 29 Jan 2009 16:30:11 GMT</pubDate></item><item><title><![CDATA[Reply to std::set::find-Problem on Thu, 29 Jan 2009 16:37:15 GMT]]></title><description><![CDATA[<p>Decimad schrieb:</p>
<blockquote>
<p>Also meine Frage: Gibt es irgendwie eine Möglichkeit, die effiziente Suche in einem set so anzupassen, dass das zu vergleichende Objekt nicht vom Typ der im set gespeicherten Objekte sein muss (d.h. dass ich derefenzieren und eine Methode aufrufen kann, um sie kompatibel zu machen).</p>
</blockquote>
<p>Hallo Michael,</p>
<p>ich glaube, dass es diese Möglichkeit nicht gibt. Entweder Du nimmst eine std::map oder Du konstruierst eine Dummy-Klasse, die auch von Deinem besagten Interface abgeleitet ist und nur den Namen unterstützt. Ich unterstelle dabei , dass Dein set etwa so aussieht:</p>
<pre><code class="language-cpp">std::set&lt; boost::shared_ptr&lt; ICommonInterface &gt; &gt;
</code></pre>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1654482</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1654482</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 29 Jan 2009 16:37:15 GMT</pubDate></item><item><title><![CDATA[Reply to std::set::find-Problem on Thu, 29 Jan 2009 16:46:51 GMT]]></title><description><![CDATA[<p>Hallo Werner!<br />
Vielen Dank, ich befürchtete das schon. Aus den Eigenschaften der Objekte, die diese Schnittstelle implementieren, würde leider folgen, dass ich jedes Mal eines Deiner vorgeschlagenen &quot;Proxy&quot;-Objekte auf dem Heap konstruieren müsste. Daher werde ich wieder den &quot;Weg des geringsten Widerstandes&quot; aka. std::map beschreiten. <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>
<p>Viele Grüße,<br />
Michael</p>
<p>PS: Wobei ich natürlich auch ein temporäres Objekt auf dem Stack erstellen könnte und einen shared_ptr mit null_deleter darauf zeigen lassen könnte. Aber... hmmm... naja <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/1654489</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1654489</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 29 Jan 2009 16:46:51 GMT</pubDate></item><item><title><![CDATA[Reply to std::set::find-Problem on Thu, 29 Jan 2009 17:07:54 GMT]]></title><description><![CDATA[<p>Hallo Michael,</p>
<p>eine - zumindest theoretische Möglichkeit - wäre, einen Wrapper zu bauen, der aus einem Namen und besagten shared_ptr besteht. Bei Deinem Objekten ist der Name leer. Beim Vergleichsobjekt ist der Name gefüllt und der shared_ptr leer. Dann hast Du einen set&lt; Wrapper &gt; und passt die Vergleichsmethode entsprechend an, so dass dort immer der richtige Name gewählt wird.</p>
<p>Auf das Interface greifst Du zu, indem Du eine Funktion</p>
<pre><code class="language-cpp">ICommonInterface* get_pointer( Wrapper&amp; wrapper )
</code></pre>
<p>schreibst. Dann kannst Du zumindest mit der Kombination von Algorithmen und boost:bind, wie gewohnt auf die Elemente zugreifen, als ob es sich um shared_ptr handelt. (siehe dazu <a href="http://www.boost.org/doc/libs/1_37_0/libs/bind/mem_fn.html" rel="nofollow">http://www.boost.org/doc/libs/1_37_0/libs/bind/mem_fn.html</a> die Stelle 'Library authors can &quot;register&quot; their smart pointer classes ...')</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1654512</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1654512</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 29 Jan 2009 17:07:54 GMT</pubDate></item><item><title><![CDATA[Reply to std::set::find-Problem on Fri, 30 Jan 2009 19:05:55 GMT]]></title><description><![CDATA[<p>Da habe ich doch glatt Deine letzte Antwort verpasst!<br />
Das wäre selbstverständlich auch eine gangbare Alternative; das merke ich mir auf jeden Fall für Situationen vor, in denen ich wirklich nur mit absolut schlechtem Gewissen den Schlüssel für einen std::map duplizieren würde. Ich hatte mir auch überlegt, dass mann dann evtl. einen id-proxy (Irgendwie mag ich das wort proxy :D) als Schlüssel in der map einsetzen könnte, dessen Konstruktion für eine etwaige Suche zumindest einfacher handhabbar ist (weil die Einschränkungen aufgrund der Schnittstelle der gespeicherten Objekte damit wegfallen). Das könnte sich dann unter Umständen bei sehr komplizierten Schlüsseln lohnen. Einen Vergleich mit Deinem Ansatz habe ich aber noch nicht vollständig gezogen.<br />
Nachdem ich nochmal darüber geschlafen habe, war es mir dann heute relativ egal, dass ich lieber auf std::set gesetzt hätte <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>
<p>Vielen Dank und beste Grüße,<br />
Michael</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1655174</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1655174</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Fri, 30 Jan 2009 19:05:55 GMT</pubDate></item></channel></rss>