Boost C++ Libraries: Ticket #5991: find_ptr (find wrapper) https://svn.boost.org/trac10/ticket/5991 <p> Could you add a find wrapper to multi_index that returns value_type* instead of an iterator (and NULL if not found)? </p> <p> It'd allow code like: </p> <pre class="wiki">if (auto i = c.find_ptr("key")) { } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5991 Trac 1.4.3 Joaquín M López Muñoz Sun, 09 Oct 2011 19:14:21 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/5991#comment:1 https://svn.boost.org/trac10/ticket/5991#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> I don't think this is sufficiently useful as to be included in the general API of Boost.<a class="missing wiki">MultiIndex</a> (for one, no container in STL or Boost does it.) In any case, you can roll your own find_ptr utility: </p> <pre class="wiki">template&lt;typename Container,typename Key&gt; const typename Container::value_type* find_ptr(const Container&amp;c,const Key&amp; k) { auto i=c.find(k); return i==c.end()?0:&amp;*i; } ... if(auto p=find_ptr(c,5)){...} </pre> Ticket Olaf van der Spek <olafvdspek@…> Sun, 09 Oct 2011 19:40:59 GMT <link>https://svn.boost.org/trac10/ticket/5991#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:2</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:1" title="Comment 1">joaquin</a>: </p> <blockquote class="citation"> <p> I don't think this is sufficiently useful as to be included in the general API of Boost.<a class="missing wiki">MultiIndex</a> (for one, no container in STL or Boost does it.) </p> </blockquote> <p> Someone has to be first, right? </p> <blockquote class="citation"> <p> In any case, you can roll your own find_ptr utility: </p> </blockquote> <p> Already got one for std::map etc, but not yet for std::set. I thought multi_index required a different function, but it can use the same as std::set. So it probably shouldn't be a member function. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joaquín M López Muñoz</dc:creator> <pubDate>Mon, 10 Oct 2011 05:47:12 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:2" title="Comment 2">Olaf van der Spek &lt;olafvdspek@…&gt;</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:1" title="Comment 1">joaquin</a>: </p> <blockquote class="citation"> <p> I don't think this is sufficiently useful as to be included in the general API of Boost.<a class="missing wiki">MultiIndex</a> (for one, no container in STL or Boost does it.) </p> </blockquote> <p> Someone has to be first, right? </p> </blockquote> <p> Yes of course, but in this case I don't think the use case presented is so prominent as to deserve a dedicated built-in feature. </p> <blockquote class="citation"> <blockquote class="citation"> <p> In any case, you can roll your own find_ptr utility: </p> </blockquote> <p> Already got one for std::map etc, but not yet for std::set. I thought multi_index required a different function, but it can use the same as std::set. So it probably shouldn't be a member function. </p> </blockquote> <p> What's wrong with the example find_ptr function template given above? It should work with any container providing a find member function --I don't see the need to have separate functions for map, set, etc. </p> </description> <category>Ticket</category> </item> <item> <author>Olaf van der Spek <olafvdspek@…></author> <pubDate>Mon, 10 Oct 2011 09:21:34 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:4</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:3" title="Comment 3">joaquin</a>: </p> <blockquote class="citation"> <blockquote class="citation"> <p> Already got one for std::map etc, but not yet for std::set. I thought multi_index required a different function, but it can use the same as std::set. So it probably shouldn't be a member function. </p> </blockquote> <p> What's wrong with the example find_ptr function template given above? It should work with any container providing a find member function --I don't see the need to have separate functions for map, set, etc. </p> </blockquote> <p> The map variant returns a pointer to second. A variant for containers that store pointers performs an additional dereference. IMO the wrapper is useful every time you use a map like container. </p> </description> <category>Ticket</category> </item> <item> <author>Olaf van der Spek <olafvdspek@…></author> <pubDate>Thu, 03 Nov 2011 12:51:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:5</guid> <description> <p> Joaquín? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joaquín M López Muñoz</dc:creator> <pubDate>Thu, 03 Nov 2011 13:14:30 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:4" title="Comment 4">Olaf van der Spek &lt;olafvdspek@…&gt;</a>: </p> <blockquote class="citation"> <p> The map variant returns a pointer to second. A variant for containers that store pointers performs an additional dereference. </p> </blockquote> <p> Why a pointer to second? This is not consistent with the semantics of std::map, which returns an iterator to the whole element (the key-value pair), not the value alone. </p> <blockquote class="citation"> <p> IMO the wrapper is useful every time you use a map like container. </p> </blockquote> <p> In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request. </p> </description> <category>Ticket</category> </item> <item> <author>Olaf van der Spek <olafvdspek@…></author> <pubDate>Thu, 03 Nov 2011 15:02:04 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:7</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:6" title="Comment 6">joaquin</a>: </p> <blockquote class="citation"> <p> Why a pointer to second? </p> </blockquote> <p> Because the key is known already. </p> <blockquote class="citation"> <p> This is not consistent with the semantics of std::map, which returns an iterator to the whole element (the key-value pair), not the value alone. </p> </blockquote> <p> std::map doesn't have find_ptr(). </p> <blockquote class="citation"> <blockquote class="citation"> <p> IMO the wrapper is useful every time you use a map like container. </p> </blockquote> <p> In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request. </p> </blockquote> <p> Can it? I can't (easily) select another overload for containers (like multi_index) that don't have a pair value_type. </p> <p> My find_ptr() for std::map (and std::unordered_map, boost::ptr_map, etc): </p> <pre class="wiki">template &lt;class T, class U&gt; typename T::value_type::second_type* find_ptr(T&amp; c, U v) { typename T::iterator i = c.find(v); return i == c.end() ? NULL : &amp;i-&gt;second; } template &lt;class T, class U&gt; const typename T::value_type::second_type* find_ptr(const T&amp; c, U v) { typename T::const_iterator i = c.find(v); return i == c.end() ? NULL : &amp;i-&gt;second; } template &lt;class T, class U&gt; typename T::value_type::second_type find_ptr2(T&amp; c, U v) { typename T::iterator i = c.find(v); return i == c.end() ? NULL : i-&gt;second; } template &lt;class T, class U&gt; const typename T::value_type::second_type find_ptr2(const T&amp; c, U v) { typename T::const_iterator i = c.find(v); return i == c.end() ? NULL : i-&gt;second; } </pre> </description> <category>Ticket</category> </item> <item> <author>Olaf van der Spek <olafvdspek@…></author> <pubDate>Thu, 03 Nov 2011 15:23:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:8</guid> <description> <p> Look at <a href="http://www.boost.org/doc/libs/1_47_0/libs/multi_index/example/bimap.cpp">http://www.boost.org/doc/libs/1_47_0/libs/multi_index/example/bimap.cpp</a> for example. </p> <pre class="wiki">dictionary::iterator it=get&lt;from&gt;(d).find(word); if(it!=d.end()){ std::cout&lt;&lt;word&lt;&lt;" is said "&lt;&lt;it-&gt;second&lt;&lt;" in English"&lt;&lt;std::endl; } </pre><ol><li>Shouldn't it be get&lt;from&gt;(d).end()? </li><li>You're not using it-&gt;first. </li></ol><p> With bimaps though, you'd probably want to return a ptr to the pair. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joaquín M López Muñoz</dc:creator> <pubDate>Fri, 04 Nov 2011 07:37:07 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:9</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:7" title="Comment 7">Olaf van der Spek &lt;olafvdspek@…&gt;</a>: </p> <blockquote class="citation"> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:6" title="Comment 6">joaquin</a>: </p> <blockquote class="citation"> <p> Why a pointer to second? </p> </blockquote> <p> Because the key is known already. </p> <blockquote class="citation"> <p> This is not consistent with the semantics of std::map, which returns an iterator to the whole element (the key-value pair), not the value alone. </p> </blockquote> <p> std::map doesn't have find_ptr(). </p> </blockquote> <p> Of course, but it has find(), which I understand you're copying semantics from, except that you return a pointer (null if no element was found) rather than an iterator (pointing to end if no element was found.) </p> <blockquote class="citation"> <p> </p> <blockquote class="citation"> <blockquote class="citation"> <p> IMO the wrapper is useful every time you use a map like container. </p> </blockquote> <p> In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request. </p> </blockquote> <p> Can it? I can't (easily) select another overload for containers (like multi_index) that don't have a pair value_type. </p> </blockquote> <p> multi_index_containers don't sport a notion of second_type. But you can use the same wrapper as you're currently doing with std::set. Remember this conversarion began with your request for a member function returning a value_type* (not a pointer to the second part of the value.) </p> <p> What problems are you having with defining an overload for multi_index_containers? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Joaquín M López Muñoz</dc:creator> <pubDate>Fri, 04 Nov 2011 07:39:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:10</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:8" title="Comment 8">Olaf van der Spek &lt;olafvdspek@…&gt;</a>: </p> <blockquote class="citation"> <p> Look at <a href="http://www.boost.org/doc/libs/1_47_0/libs/multi_index/example/bimap.cpp">http://www.boost.org/doc/libs/1_47_0/libs/multi_index/example/bimap.cpp</a> for example. </p> <pre class="wiki">dictionary::iterator it=get&lt;from&gt;(d).find(word); if(it!=d.end()){ std::cout&lt;&lt;word&lt;&lt;" is said "&lt;&lt;it-&gt;second&lt;&lt;" in English"&lt;&lt;std::endl; } </pre><ol><li>Shouldn't it be get&lt;from&gt;(d).end()? </li></ol></blockquote> <p> Not strictly necessary: if you don't specify the index it's as if you're using the first one. </p> <blockquote class="citation"> <ol start="2"><li>You're not using it-&gt;first. </li></ol></blockquote> <p> So? I'm not getting your point. </p> </description> <category>Ticket</category> </item> <item> <author>Olaf van der Spek <olafvdspek@…></author> <pubDate>Fri, 04 Nov 2011 09:25:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5991#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5991#comment:11</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5991#comment:9" title="Comment 9">joaquin</a>: </p> <blockquote class="citation"> <p> Of course, but it has find(), which I understand you're copying semantics from, except that you return a pointer (null if no element was found) rather than an iterator (pointing to end if no element was found.) </p> </blockquote> <p> True. Ideally I'd like to have find_ptr() for all containers that have a find(). </p> <blockquote class="citation"> <blockquote class="citation"> <p> </p> <blockquote class="citation"> <blockquote class="citation"> <p> IMO the wrapper is useful every time you use a map like container. </p> </blockquote> <p> In either case, find_ptr can be provided as an (overloaded) function, no need to have as a built-in member function. Thus my reluctance to address your request. </p> </blockquote> <p> Can it? I can't (easily) select another overload for containers (like multi_index) that don't have a pair value_type. </p> </blockquote> <p> multi_index_containers don't sport a notion of second_type. </p> </blockquote> <p> Right </p> <blockquote class="citation"> <p> But you can use the same wrapper as you're currently doing with std::set. Remember this conversarion began with your request for a member function returning a value_type* (not a pointer to the second part of the value.) </p> </blockquote> <p> I don't have one yet. </p> <blockquote class="citation"> <p> What problems are you having with defining an overload for multi_index_containers? </p> </blockquote> <p> I could easily define one with a different name, but I've no idea what enable_if code to use for automatic overload selection. </p> <blockquote class="citation"> <p> Not strictly necessary: if you don't specify the index it's as if you're using the first one. </p> </blockquote> <p> True, but now the code assumes from is the first index. </p> </description> <category>Ticket</category> </item> </channel> </rss>