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
#include
#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
>::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>
>::value'
: c:/boost/boost/type_traits/is_convertible.hpp:295:
instantiated from '
const bool boost::detail::is_convertible_impl<
move_from, U<int>
>::value'
c:/boost/boost/type_traits/is_convertible.hpp:418:
instantiated from 'boost::is_convertible, U<int> >'
c:/boost/boost/utility/enable_if.hpp:36:
instantiated from 'boost::enable_if<
boost::is_convertible, 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) [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) [with T = int]'