While reading about the move constructor from the current standard, I can see the following about this:
12.8 Copying and moving class objects
If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
— X does not have a user-declared copy constructor,
— X does not have a user-declared copy assignment operator,
— X does not have a user-declared move assignment operator, and
— X does not have a user-declared destructor.[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. — end note ]
I think note section clearly mentions that fall-back for default move constructor would be copy constructor. To understand this concept I wrote the small program to understand this concept.
#include<iostream>
struct handleclass {
public:
handleclass():length{0}, p{nullptr} {}
handleclass(size_t l):length{l},p{new int[length]} { }
~handleclass() { delete[] p; }
size_t length;
int* p;
};
handleclass function(void) {
handleclass x(10);
return x;
}
int main() {
handleclass y;
std::cout<<y.length<<std::endl;
y = function();
std::cout<<y.length<<std::endl;
handleclass a;
handleclass b(10);
a = std::move(b);
return 0;
}
Obviously this program is incorrect and would have undefined behaviour(terminate) due to the shallow copy of resources by two objects. But my focus is to understand the default move constructor generated and used in program. I hope this example make sense.
In the above program, in both cases where move constructor should be called, it appears to me that compiler is using default copy constructor.
Based on the above rule mentioned in the standard I think we should have got the compiler error as now program explicitly trying to call the move constructor and neither user has implemented nor compiler generates default(implicitly) as above rule does not satisfy?.
However this is getting compiled without any warning/error and running successfully. Could somebody explains about default(implicitly) move constructor concepts? Or I am missing something?.