[Boost-bugs] [Boost C++ Libraries] #9910: is_convertible doesn't compile with inaccessible copy constructor

Subject: [Boost-bugs] [Boost C++ Libraries] #9910: is_convertible doesn't compile with inaccessible copy constructor
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-04-15 15:47:38


#9910: is_convertible doesn't compile with inaccessible copy constructor
-----------------------------------+-------------------------
 Reporter: Matei David <matei@…> | Owner: johnmaddock
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: type_traits
  Version: Boost 1.55.0 | Severity: Problem
 Keywords: is_convertible |
-----------------------------------+-------------------------
 I found a situation where (with `gcc-4.8.2` & `boost-1.55`) I cannot
 compile a call to `boost::is_convertible`, but I can compile a similar
 call to `std::is_convertible`. This is a bug, unless it is undefined
 behaviour to pass `is_convertible` a type with a private or deleted copy
 constructor. If it is a bug, it is a `boost` bug, not a `gcc` bug
 (explained below).

 Here is the discordant code:
 {{{
 #include <type_traits>
 #include <boost/type_traits/is_convertible.hpp>
 struct A {
     A() = default;
     A(const A&) = delete; // or private: A(const A&) = default;
 };
 struct Ref_A { // proxy reference to A
     operator A& () { return *_ptr; }
     A* _ptr;
 };
 int main() {
     (void)std::is_convertible< Ref_A, A >::value;
     (void)boost::is_convertible< Ref_A, A >::value;
 }
 }}}
 I compile with:
 `{g++|clang++} -std=c++11 -I${BOOST_INCLUDE} -Wall -Wextra -c`

 With `gcc-4.8.2`, the call to `boost::is_convertible` fails to compile,
 complaining that the copy constructor of A is deleted (or private.) The
 similar call to `std::is_convertible` compiles ok (and returns false, but
 that is irrelevant).

 With `clang-3.4`, both calls compile. The reason for the discrepancy is
 that `boost/type_traits/intrinsics.hpp` defines the macro
 `BOOST_IS_CONVERTIBLE(T,U)` for `clang`, but not for `gcc`. Because of
 that, at the bottom of `boost/type_traits/is_convertible.hpp`, `clang`
 uses the macro to implement `is_convertible`, whereas `gcc` uses
 `is_convertible_impl_dispatch` instead (which is the one that fails).
 That's why I said this is not a `gcc` bug.

 A temporary fix I found is to define that macro to defer to `std`:
 {{{
 #include <type_traits>
 #include <boost/type_traits/intrinsics.hpp>
 #ifndef BOOST_IS_CONVERTIBLE
 #define BOOST_IS_CONVERTIBLE(T, U) (std::is_convertible<T, U>::value)
 #endif
 #include <boost/type_traits/is_convertible.hpp>
 }}}
 Which `type_traits` library should we prefer these days, post `c++11`?
 Intuition says `std` should be more stable/portable, is that wrong? If it
 is indeed `std`, is there a way (perhaps a macro?) to make `boost` mirror
 `std` (I'm talking about `type_traits` only). The reason for having such a
 mirror option is not for new code, but for other `boost` libraries which
 need `type_traits`. E.g, I came across this issue from `boost::iterator`.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/9910>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:16 UTC