Boost C++ Libraries: Ticket #9910: is_convertible doesn't compile with inaccessible copy constructor https://svn.boost.org/trac10/ticket/9910 <p> I found a situation where (with <code>gcc-4.8.2</code> &amp; <code>boost-1.55</code>) I cannot compile a call to <code>boost::is_convertible</code>, but I can compile a similar call to <code>std::is_convertible</code>. This is a bug, unless it is undefined behaviour to pass <code>is_convertible</code> a type with a private or deleted copy constructor. If it is a bug, it is a <code>boost</code> bug, not a <code>gcc</code> bug (explained below). </p> <p> Here is the discordant code: </p> <pre class="wiki">#include &lt;type_traits&gt; #include &lt;boost/type_traits/is_convertible.hpp&gt; struct A { A() = default; A(const A&amp;) = delete; // or private: A(const A&amp;) = default; }; struct Ref_A { // proxy reference to A operator A&amp; () { return *_ptr; } A* _ptr; }; int main() { (void)std::is_convertible&lt; Ref_A, A &gt;::value; (void)boost::is_convertible&lt; Ref_A, A &gt;::value; } </pre><p> I compile with: <code>{g++|clang++} -std=c++11 -I${BOOST_INCLUDE} -Wall -Wextra -c</code> </p> <p> With <code>gcc-4.8.2</code>, the call to <code>boost::is_convertible</code> fails to compile, complaining that the copy constructor of A is deleted (or private.) The similar call to <code>std::is_convertible</code> compiles ok (and returns false, but that is irrelevant). </p> <p> With <code>clang-3.4</code>, both calls compile. The reason for the discrepancy is that <code>boost/type_traits/intrinsics.hpp</code> defines the macro <code>BOOST_IS_CONVERTIBLE(T,U)</code> for <code>clang</code>, but not for <code>gcc</code>. Because of that, at the bottom of <code>boost/type_traits/is_convertible.hpp</code>, <code>clang</code> uses the macro to implement <code>is_convertible</code>, whereas <code>gcc</code> uses <code>is_convertible_impl_dispatch</code> instead (which is the one that fails). That's why I said this is not a <code>gcc</code> bug. </p> <p> A temporary fix I found is to define that macro to defer to <code>std</code>: </p> <pre class="wiki">#include &lt;type_traits&gt; #include &lt;boost/type_traits/intrinsics.hpp&gt; #ifndef BOOST_IS_CONVERTIBLE #define BOOST_IS_CONVERTIBLE(T, U) (std::is_convertible&lt;T, U&gt;::value) #endif #include &lt;boost/type_traits/is_convertible.hpp&gt; </pre><p> Which <code>type_traits</code> library should we prefer these days, post <code>c++11</code>? Intuition says <code>std</code> should be more stable/portable, is that wrong? If it is indeed <code>std</code>, is there a way (perhaps a macro?) to make <code>boost</code> mirror <code>std</code> (I'm talking about <code>type_traits</code> only). The reason for having such a mirror option is not for new code, but for other <code>boost</code> libraries which need <code>type_traits</code>. E.g, I came across this issue from <code>boost::iterator</code>. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9910 Trac 1.4.3 John Maddock Wed, 23 Apr 2014 11:53:44 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9910#comment:1 https://svn.boost.org/trac10/ticket/9910#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">fixed</span> </li> </ul> <p> Fixed in develop by providing a C++11 conforming version. </p> <p> I'm not so sure about std::is_convertible being more stable/conforming: there are quite a few bugs in the compiler intrinsics for type_traits that we have to work around: indeed MSVC's std::is_convertible fails this test case! </p> Ticket Michel Morin Sat, 26 Apr 2014 16:26:03 GMT <link>https://svn.boost.org/trac10/ticket/9910#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9910#comment:2</guid> <description> <p> Hi John, </p> <p> The use of <code>is_abstract&lt;To&gt;</code> in <code>boost::detail::is_convertible_impl_dispatch_base</code> disallows <code>To</code> to be an array of incomplete types. For example, </p> <pre class="wiki">struct incomplete; bool b = is_convertible&lt;int, incomplete[]&gt;::value; </pre><p> produces a compilation error, but this code is fine in C++11. </p> <p> Michel </p> </description> <category>Ticket</category> </item> <item> <dc:creator>John Maddock</dc:creator> <pubDate>Sun, 27 Apr 2014 15:53:04 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9910#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9910#comment:3</guid> <description> <p> Fixed in <a class="ext-link" href="https://github.com/boostorg/type_traits/commit/03bff14498de17523a4348d1c9dce05d40a13d07"><span class="icon">​</span>https://github.com/boostorg/type_traits/commit/03bff14498de17523a4348d1c9dce05d40a13d07</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Michel Morin</dc:creator> <pubDate>Mon, 28 Apr 2014 14:18:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9910#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9910#comment:4</guid> <description> <p> Thanks for the fix! </p> </description> <category>Ticket</category> </item> </channel> </rss>