Boost C++ Libraries: Ticket #2704: range lock algorithm fails with iterators https://svn.boost.org/trac10/ticket/2704 <p> #include &lt;boost/thread.hpp&gt; </p> <p> #include &lt;vector&gt; </p> <p> int main() { </p> <blockquote> <p> std::vector&lt;boost::mutex&gt; v; </p> </blockquote> <blockquote> <p> <em> boost::lock(&amp;v.front(), &amp;v.front()+v.size()); boost::lock(v.begin(), v.end()); </em></p> </blockquote> <blockquote> <p> return 0; </p> </blockquote> <p> } </p> <p> With GCC 4.3.2 and 4.4 this fails to compile, complaining that std::vector&lt;mutex&gt;::iterator does not have members lock, unlock and try_lock e.g. /home/redi/src/boost/boost/thread/locks.hpp: In static member function ‘static char boost::detail::has_member_try_lock&lt;T&gt;::has_member(U*, bool (U::*)()) [with U = <span class="underline">gnu_cxx::</span>normal_iterator&lt;boost::mutex*, std::vector&lt;boost::mutex, std::allocator&lt;boost::mutex&gt; &gt; &gt;, T = <span class="underline">gnu_cxx::</span>normal_iterator&lt;boost::mutex*, std::vector&lt;boost::mutex, std::allocator&lt;boost::mutex&gt; &gt; &gt;]’: /home/redi/src/boost/boost/thread/locks.hpp:75: instantiated from ‘const bool boost::detail::has_member_try_lock&lt;<span class="underline">gnu_cxx::</span>normal_iterator&lt;boost::mutex*, std::vector&lt;boost::mutex, std::allocator&lt;boost::mutex&gt; &gt; &gt; &gt;::value’ /home/redi/src/boost/boost/thread/locks.hpp:84: instantiated from ‘const bool boost::is_mutex_type&lt;<span class="underline">gnu_cxx::</span>normal_iterator&lt;boost::mutex*, std::vector&lt;boost::mutex, std::allocator&lt;boost::mutex&gt; &gt; &gt; &gt;::value’ /home/redi/src/boost/boost/thread/locks.hpp:1133: instantiated from ‘void boost::lock(const MutexType1&amp;, const MutexType2&amp;) [with MutexType1 = <span class="underline">gnu_cxx::</span>normal_iterator&lt;boost::mutex*, std::vector&lt;boost::mutex, std::allocator&lt;boost::mutex&gt; &gt; &gt;, MutexType2 = <span class="underline">gnu_cxx::</span>normal_iterator&lt;boost::mutex*, std::vector&lt;boost::mutex, std::allocator&lt;boost::mutex&gt; &gt; &gt;]’ lock_range.cc:10: instantiated from here </p> <p> The commented-out line above compiles fine, using mutex* as the Iterator type rather than std::vector&lt;mutex&gt;::iterator. </p> <p> I don't think SFINAE applies in has_member_try_lock&lt;T&gt;::has_member&lt;U&gt;, because bool(U::*)() is a valid type for iterators classes, so substitution succeeds, but &amp;U::try_lock is not a valid expression. </p> <p> In the pointer case where U is a pointer, bool(U::*)() is not a valid type, so substitution fails, but is not an error. </p> <p> The attached patch (against trunk) adds another default argument to has_member_{lock,try_lock,unlock}::has_member with a type that depends on the presence of a member with the right name. I think this would still fail to compile if used with an iterator type that had a member lock/try_lock/unlock with a different signature to that expected by the Lockable concept. </p> <p> Jonathan </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2704 Trac 1.4.3 jwakely.boost@… Sat, 31 Jan 2009 16:15:41 GMT attachment set https://svn.boost.org/trac10/ticket/2704 https://svn.boost.org/trac10/ticket/2704 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_locks.patch</span> </li> </ul> <p> patch to use sfinae in is_mutex_type helpers </p> Ticket jwakely.boost@… Sat, 31 Jan 2009 16:23:56 GMT attachment set https://svn.boost.org/trac10/ticket/2704 https://svn.boost.org/trac10/ticket/2704 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_locks.2.patch</span> </li> </ul> <p> fixed patch to use sfinae in is_mutex_type helpers </p> Ticket jwakely.boost@… Sat, 31 Jan 2009 16:58:37 GMT attachment set https://svn.boost.org/trac10/ticket/2704 https://svn.boost.org/trac10/ticket/2704 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost_locks3.patch</span> </li> </ul> <p> take 3! this one's simpler, and doesn't fail if the iterator type happens to have a member like int Iterator::lock(int) </p> Ticket jwakely.boost@… Sat, 31 Jan 2009 17:11:05 GMT <link>https://svn.boost.org/trac10/ticket/2704#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2704#comment:1</guid> <description> <p> gah, I've just noticed that trac concatenated the lines in the original test case I posted, so that the problem line was commented out. It should be: </p> <p> <em> boost::lock(&amp;v.front(), &amp;v.front()+v.size()); </em></p> <p> boost::lock(v.begin(), v.end()); </p> <p> the second line is the problem. </p> <p> Ignore the first patch, it's full of copy&amp;paste errors. The second one fixes the original test case above, but fails for an iterator type like: </p> <p> struct iterator : std::vector&lt;boost::mutex&gt;::iterator { </p> <blockquote> <p> template&lt;typename T&gt; iterator(T t) : std::vector&lt;boost::mutex&gt;::iterator(t) { } </p> </blockquote> <blockquote> <p> iterator() : std::vector&lt;boost::mutex&gt;::iterator() { } </p> </blockquote> <blockquote> <p> iterator&amp; operator++(); </p> </blockquote> <blockquote> <p> iterator operator++(int); </p> </blockquote> <blockquote> <p> bool lock(int); <em> confuses has_member_lock </em></p> </blockquote> <p> }; </p> <p> The lock member means substitution succeeds, but the "dummy" parameter fails to compile because the signature of &amp;U::lock doesn't match. </p> <p> The third patch handles the case above by extending sfinae_type to only succeed for members with the right signature. </p> </description> <category>Ticket</category> </item> <item> <author>Jonathan Wakely <jwakely.boost@…></author> <pubDate>Fri, 05 Jun 2009 17:00:16 GMT</pubDate> <title>cc set https://svn.boost.org/trac10/ticket/2704#comment:2 https://svn.boost.org/trac10/ticket/2704#comment:2 <ul> <li><strong>cc</strong> <span class="trac-author">jwakely.boost@…</span> added </li> </ul> Ticket viboes Tue, 08 Jun 2010 11:56:09 GMT <link>https://svn.boost.org/trac10/ticket/2704#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2704#comment:3</guid> <description> <p> boost::mutex is not copyable, so you can not put them on std::vector. You will need to wait until there is a common move semantics emulation and the associated containers. </p> <p> Could we close this ticket, or change it as a Feature request? </p> </description> <category>Ticket</category> </item> <item> <author>Jonathan Wakely <jwakely.boost@…></author> <pubDate>Tue, 08 Jun 2010 12:09:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2704#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2704#comment:4</guid> <description> <p> The bug is not "mutex is not copyable" it is that the range lock algo doesn't work with iterators. The original testcase does not require mutex to be copyable, because it doesn't insert any mutexes into the vector. But it still fails to compile, because of a bug in boost::lock. </p> <p> If it helps you understand the problem I'll try to come up with a different test case that uses a type that is Lockable and Copyable, instead of boost::mutex </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Anthony Williams</dc:creator> <pubDate>Tue, 08 Jun 2010 12:10:46 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/2704#comment:5 https://svn.boost.org/trac10/ticket/2704#comment:5 <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">fixed</span> </li> </ul> <p> Fixed on trunk </p> Ticket