[type_traits] is_convertible bug with gcc 4.3.0

I'm playing with move semantics (still/again). The following program compiles and runs fine with msvc8 but does not compile with gcc 4.3.0 when ENABLE_IS_CONVERTIBLE_CHECK is defined. Should it? The problem has something to do with U's copy constructor being private. I've inluded the compiler output below too. terry ============================================ #include <boost/type_traits.hpp> #include <boost/utility/enable_if.hpp> #include <cassert> template <typename T> class move_from { private: T* _source; public: explicit move_from(T& x) : _source(&x) { } T& get() const { return *_source; } }; // move_from #define ENABLE_IS_CONVERTIBLE_CHECK template <typename T> inline move_from<T> move(T& x #ifdef ENABLE_IS_CONVERTIBLE_CHECK , typename boost::enable_if< boost::is_convertible<move_from<T>, T> >::type* = 0 #endif ) { return move_from<T>(x); } template <typename T> class U { T* _ptr; public: void reset(T* p=0) { delete _ptr; _ptr = p; } T* release() { T* rval = _ptr; _ptr = 0; return rval; } U() : _ptr(0) { } U(T* x) : _ptr(x) { } U(move_from<U> x) : _ptr(x.get().release()) { } U& operator=(move_from<U> x) { reset(x.get().release()); } T* get() const { return _ptr; } T* operator->() const { return get(); } T& operator*() const { return *get(); } private: explicit U(const U&); U& operator=(const U&); }; // U int main() { U<int> x(new int(1234)); U<int> z(move(x)); // Seems to convert ok here. assert(*z == 1234); assert(!x.get()); return 0; } // main ============================================ In file included from c:/boost/boost/type_traits.hpp:38, from bug.cpp:1: c:/boost/boost/type_traits/is_convertible.hpp: In instantiation of ' const bool boost::detail::is_convertible_basic_impl< move_from<U<int> >&, U<int> >::value' : c:/boost/boost/type_traits/is_convertible.hpp:295: instantiated from ' const bool boost::detail::is_convertible_impl< move_from<U<int> >, U<int> >::value' c:/boost/boost/type_traits/is_convertible.hpp:418: instantiated from 'boost::is_convertible<move_from<U<int> >, U<int> >' c:/boost/boost/utility/enable_if.hpp:36: instantiated from 'boost::enable_if< boost::is_convertible<move_from<U<int> >, U<int> >, void >' bug.cpp:46: instantiated from here c:/boost/boost/type_traits/is_convertible.hpp:136: error: no matching function for call to 'U<int>::U(U<int>)' bug.cpp:34: note: candidates are: U<T>::U(move_from<U<T> >) [with T = int] bug.cpp:33: note: U<T>::U(T*) [with T = int] c:/boost/boost/type_traits/is_convertible.hpp:136: error: initializing argument 1 of ' static boost::type_traits::yes_type boost::detail::checker<T>::_m_check(T, int) [with T = U<int>]' from result of 'U<T>::U(move_from<U<T> >) [with T = int]'

Terry G wrote:
I'm playing with move semantics (still/again).
The following program compiles and runs fine with msvc8 but does not compile with gcc 4.3.0 when ENABLE_IS_CONVERTIBLE_CHECK is defined. Should it? The problem has something to do with U's copy constructor being private. I've inluded the compiler output below too.
Without some compiler supplied magic, is_convertible will fail to compile if the conversion involves a protected or private constructor. Sorry, but it's a limitation of the implementation/language. John.
participants (2)
-
John Maddock
-
Terry G