Boost C++ Libraries: Ticket #10128: Use lockable_adapter with const objects or const members https://svn.boost.org/trac10/ticket/10128 <p> I would like to use lockable_adapter pattern with const objects. Usually, we need to access in protected mode to one const object (read some value). </p> <p> We have a compiler error when we connect unique_lock and one derived class from lockable_adapter and the object is const. </p> <pre class="wiki">int func(const Class1&amp; obj) { boost::unique_lock&lt;Class1&gt; lock(obj); //boost::unique_lock&lt;Class1&gt; lock(const_cast&lt;Class1&amp;&gt;(obj)); return obj.get(); } </pre><blockquote> <p> -&gt; </p> </blockquote> <pre class="wiki">error C2664: 'boost::unique_lock&lt;Mutex&gt;::unique_lock(boost::upgrade_lock&lt;Mutex&gt; &amp;)' : no se puede convertir el parámetro 1 de 'const Class1' a 'boost::upgrade_lock&lt;Mutex&gt; &amp;' </pre><p> The solution for us is rewrite the sentence with one const_cast&lt;Class1&gt; -&gt; boost::unique_lock&lt;Class1&gt; lock(const_cast&lt;Class1&amp;&gt;(obj)); </p> <p> We are using Visual C++ 2010 </p> <p> Best regards </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10128 Trac 1.4.3 anonymous Tue, 17 Jun 2014 11:06:48 GMT attachment set https://svn.boost.org/trac10/ticket/10128 https://svn.boost.org/trac10/ticket/10128 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">example_lock_constObject.cpp</span> </li> </ul> <p> Error example </p> Ticket viboes Tue, 17 Jun 2014 16:14:31 GMT owner, status, description changed https://svn.boost.org/trac10/ticket/10128#comment:1 https://svn.boost.org/trac10/ticket/10128#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Anthony Williams</span> to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> <li><strong>description</strong> modified (<a href="/trac10/ticket/10128?action=diff&amp;version=1">diff</a>) </li> </ul> Ticket viboes Tue, 17 Jun 2014 16:34:48 GMT <link>https://svn.boost.org/trac10/ticket/10128#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:2</guid> <description> <p> The error I'm seen is </p> <pre class="wiki">test_10128.cpp: In function ‘int func(const Class1&amp;)’: test_10128.cpp:29:40: erreur: no matching function for call to ‘boost::unique_lock&lt;Class1&gt;::unique_lock(const Class1&amp;)’ boost::unique_lock&lt;Class1&gt; lock(obj); </pre><p> A unique_lock&lt;Class1&gt; doesn't accepts a const&amp; Class1 reference. </p> <p> You wold need to use </p> <pre class="wiki"> boost::unique_lock&lt;const Class1&gt; lock(obj); </pre><p> And this patch </p> <pre class="wiki">--- a/include/boost/thread/lockable_adapter.hpp +++ b/include/boost/thread/lockable_adapter.hpp @@ -37,11 +37,11 @@ namespace boost basic_lockable_adapter() {} - void lock() + void lock() const { lockable().lock(); } - void unlock() + void unlock() const { lockable().unlock(); } </pre><p> Please, could you tell me if this work for you? </p> <blockquote> <p> <sup> </sup></p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 18 Jun 2014 08:01:03 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:3</guid> <description> <p> For me this patch is enough. It's working properly in visual C++ 2010. I suppose, it will be necesary this modification in *_lockable_adapter as timed_lockable_adapter, shared_lockable_adapter, upgrade_lockable_adapter... </p> <p> Thank you very much. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Fri, 04 Jul 2014 05:53:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:4</guid> <description> <p> After more thoughts, I have some doubts. I'm not sure it is correct to make these lock/unlock functions const. These functions are public making the nested mutex a salient attribute. </p> <p> It would be different is the mutex was not salient. E.g. synchronized_value wraps a type and makes the synchronized mutex not salient. Please, could you see if you can use synchronized_value instead? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Fri, 04 Jul 2014 06:34:04 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:5</guid> <description> <p> After yet more thoughts, lockable_adapter&lt;const X&gt; could be specialized so that the lock/unlcok operations do nothing (as there is no writter) and are const. What do you think? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 07 Jul 2014 08:29:44 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:6</guid> <description> <p> For me, this last thought is better. Then, I suppose, we can use lockable_adapeter&lt;const X&gt;. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Mon, 07 Jul 2014 10:59:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:7</guid> <description> <p> There is a little problem as we can not change the inheritance of CLass1 :( </p> <pre class="wiki">class Class1 : lockable_adapter&lt;Class1&gt; {...}; </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 07 Jul 2014 15:40:32 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:8</guid> <description> <p> Ok. I can specialize lockable_adapter&lt;Class1&gt; with const members. Are you in agree with me? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Mon, 07 Jul 2014 20:27:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:9</guid> <description> <p> How would you write your class Class1 on the example? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Tue, 08 Jul 2014 08:44:04 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:10</guid> <description> <p> I could derive lockable_adapter to lockable_adapter2 and use its const members. </p> <pre class="wiki"> template &lt;typename BasicLockable&gt; class basic_lockable_adapter2 : public boost::basic_lockable_adapter&lt;BasicLockable&gt; { public: basic_lockable_adapter2() {} void lock() const { lockable().lock(); } void unlock() const { lockable().unlock(); } }; class Class1 : public basic_lockable_adapter2&lt;boost::recursive_mutex&gt; { public: Class1() :_i(0){} virtual ~Class1(){} void set(int i) { _i = i; } int get() const { return _i; } private: int _i; }; </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 08 Jul 2014 17:33:38 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:11</guid> <description> <p> This doesn't corresponds to a const specialization of lockable_adapter. </p> <p> BTW, I'm really thinking about the usefulness of lockable_adapter :( What about </p> <pre class="wiki">class Class1 : boost::recursive_mutex { ... }; </pre><p> ? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Tue, 08 Jul 2014 18:27:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:12 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:12</guid> <description> <p> Then, If I try to change class1 with this code </p> <pre class="wiki">class Class1 : public boost::recursive_mutex { public: Class1() :_i(0){} virtual ~Class1(){} void set(int i) { _i = i; } int get() const { return _i; } private: int _i; }; int func(const Class1&amp; obj) { boost::unique_lock&lt;const Class1&gt; lock(obj); //boost::unique_lock&lt;Class1&gt; lock(obj); //boost::unique_lock&lt;Class1&gt; lock(const_cast&lt;Class1&amp;&gt;(obj)); return obj.get(); } int _tmain(int argc, _TCHAR* argv[]) { Class1 obj; { boost::unique_lock&lt;Class1&gt; lock(obj); obj.set(1); } func(obj); return 0; } </pre><p> Visual C++ 2010 says me: </p> <pre class="wiki">1&gt;c:\desarrollo\externo\boost\boost_1_55_0\boost\thread\lock_types.hpp(331): error C2662: 'boost::detail::basic_recursive_mutex_impl&lt;underlying_mutex_type&gt;::unlock' : no se puede convertir el puntero 'this' de 'const Class1' a 'boost::detail::basic_recursive_mutex_impl&lt;underlying_mutex_type&gt; &amp;' 1&gt; with 1&gt; [ 1&gt; underlying_mutex_type=boost::detail::basic_timed_mutex 1&gt; ] 1&gt; Se pierden calificadores en la conversión 1&gt; c:\desarrollo\externo\boost\boost_1_55_0\boost\thread\lock_types.hpp(328) : durante la compilación de la función miembro de plantilla de clase 'boost::unique_lock&lt;Mutex&gt;::~unique_lock(void)' 1&gt; with 1&gt; [ 1&gt; Mutex=const Class1 1&gt; ] 1&gt; c:\temp\example_lock_constobject\example_lock_constobject.cpp(50) : vea la referencia a la creación de instancias de plantilla de clase 'boost::unique_lock&lt;Mutex&gt;' que se está compilando 1&gt; with 1&gt; [ 1&gt; Mutex=const Class1 1&gt; ] </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Sat, 12 Jul 2014 08:04:38 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:13</guid> <description> <p> Off course :( </p> <p> I don't see how the code in comment 10 would compile after having a specialization for const X. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Fri, 25 Jul 2014 11:49:14 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/10128#comment:14 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10128#comment:14</guid> <description> <p> Then, I'm afraid, I will use a member mutex in Class1 with "boost::unique_lock&lt;boost::recursive_mutex&gt; sl(m_mt)" </p> <p> Thank you very much for your time. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Mon, 28 Jul 2014 06:37:17 GMT</pubDate> <title>status changed; resolution set; milestone deleted https://svn.boost.org/trac10/ticket/10128#comment:15 https://svn.boost.org/trac10/ticket/10128#comment:15 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> <li><strong>milestone</strong> <span class="trac-field-deleted">To Be Determined</span> </li> </ul> Ticket