from N3337:
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, X does not have a user-declared destructor, and the move constructor would not be implicitly defined as deleted.
The first question is: why compiler generates move constructor when it shouldn't (there is user declared destructor and other functions which prevents generation of move constructor).
Example program below prints constructorCounter=5
which means that there used move constructor (without move operations value::constructorCounter should be 10)
#include <iostream>
class value {
public:
value() {
++constructorCounter;
}
value(const int value)
: _value(value)
{
++constructorCounter;
}
value(const value& other)
: _value(other._value)
{
++constructorCounter;
}
const value& operator=(const value& rhs) {
_value = rhs._value;
return _value;
}
~value() { }
static int constructorCounter;
private:
int _value;
};
int value::constructorCounter = 0;
class array {
public:
// array() = delete;
// array(array&&) = delete;
array(const int size)
: _size(size), _values(new value[size])
{
std::clog << "array(const int size)" << std::endl;
}
array(const array& rhs)
: array(rhs._size)
{
std::clog << "array(const array& rhs)" << std::endl;
for (int i = 0; i < _size; ++i)
_values[i] = rhs._values[i];
}
array& operator=(const array&) {
std::clog << "array& operator=(const array&)" << std::endl;
}
~array() {
delete [] _values;
}
private:
value* _values;
int _size;
};
int main(int argc, char *argv[]) {
array c(array(5));
std::clog << "constructor counter=" << value::constructorCounter << std::endl;
return 0;
}
Second related question: why program fail to compile if i disable move constructor array(array&&) = deleted;
, why there is no 'fall back' to copy consturctor array(const array&)
?
array c(array(5));
array(5) is an rvalue, therefore the move constructor will be called. – babu646