Does std::is_move_constructible<T>::value == true imply that T has a usable move constructor? If so, what is the default behaviour of it?
Consider the following case:
struct foo { int* ptr; }; int main() { { std::cout << std::is_move_constructible<foo>::value << '\n'; foo f; f.ptr = (int*)12; foo f2(std::move(f)); std::cout << f.ptr << ' ' << f2.ptr << '\n'; } return 0; } and the output is:
1 0000000C 0000000C I thought that f.ptr should be nullptr. So in this case,
f2 move constructed ?(I'm using VS11.)
The default behaviour of move constructor is same as a copy constructor, is it correct? If it's true,
It seems that foo f2(std::move(f)); calls the copy ctor when I declared one, see:
struct foo { int* ptr; foo() {} foo(const foo& other) { std::cout << "copy constructed\n"; } }; int main() { { std::cout << std::is_move_constructible<foo>::value << '\n'; foo f; foo f2(std::move(f)); } system("pause"); return 0; } Now the output is:
1 copy constructed If foo has a move constructor, then wouldn't foo f2(std::move(f)) call it?
So now my questions is: How to know if a class has a move ctor, and if it has one, how can I explicitly call it?
template<typename T, bool has_move_ctor> struct MoveAux; template<typename T> struct MoveAux<T, true> { static void doMove(T* dest, T* src) { new(dest) T(std::move(*src)); //move ctor } }; template<typename T> struct MoveAux<T, false> { static void doMove(T* dest, T* src) { new(dest) T(*src); //copy ctor src->~T(); } }; template<typename T> inline doMove(T* dest, T* src) { MoveAux<T,/*a trait*/>::doMove(dest, src); } So I thought std::is_move_constructible<T>::value can be passed to the template, while now I see that this trait only cares if T t(T()) is a valid expression, it may call T::T(const T&). Now assume that T is a custom class, then I want the above templates to behave like:
MoveAux<T,false>::doMove.MoveAux<T,true>::doMove.Is it possible to make this work?
does
std::is_move_constructible<T>::value == trueimplies thatThas a usable move constructor?
Either a move constructor or a copy constructor. Remember that the operation of copy construction satisfies all the requirements that are placed upon the operation move construction, and some more.
In Standard terms, a MoveConstructible object is one for which the evaluation of the expression:
T u = rv; makes u equivalent to the value of rv before the construction; the state of rv after being moved-from is unspecified. But since it is unspecified, this means the state could even be identical to the one rv had before being moved from: In other words, u could be a copy of rv.
In fact, the Standard defines the CopyConstructible concept to be a refinement of the MoveConstructible concept (so everything which is CopyConstructible is also MoveConstructible, but not vice versa).
if so, what is the default behaviour of it?
The behavior of an implicitly generated move constructor is to perform a member-wise move of the data members of the type for which it is generated.
Per Parahgraph 12.8/15 of the C++11 Standard:
The implicitly-defined copy/move constructor for a non-union class
Xperforms a memberwise copy/move of its bases and members. [ Note: brace-or-equal-initializers of non-static data members are ignored. See also the example in 12.6.2. —end note ]
Moreover:
1 - is
f2move constructed ?
Yes.
2 - if so, shouldn't the rvalue be invalidated?
Moving a pointer is the same as copying it. So no invalidation is going on, neither should it be going on. If you want a move constructor that leaves the moved-from object in a particular state (i.e. sets a pointer data member to nullptr), you have to write your own - or delegate this responsibility to some smart pointer class such as std::unique_ptr.
Notice, that the word "invalidated" is not quite correct here. Move constructors (as well as move assignment operators) are meant to leave the moved-from object in a valid (yet unspecified) state.
In other words, the class invariant needs to be respected - and it should be possible to invoke on a moved-from objects operations that do not have any precondition on its state (usually, destruction and assignment).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With