In The C++ Programming Language 4th edition
, the author says that
• If the programmer declares a copy operation, a move operation, or a destructor for a class, no copy operation, move operation, or destructor is generated for that class.
• If the programmer declares any constructor for a class, the default constructor is not generated for that class.
So I was trying to see that in action, so I implemented an example that is also in the book, a simple class that has an std::vector
member, an implementation of a default constructor and a copy assignment operator.
#include <iostream>
#include <vector>
#include <type_traits>
class tic {
public:
tic() : p(9) {}
tic &operator=(const tic& t) {
for(int i = 0; i < t.p.size(); i++)
p.at(i) = t.p.at(i);
return *this;
}
private:
std::vector<int> p;
};
int main() {
std::cout << std::boolalpha;
std::cout << std::is_move_constructible<tic>::value <<
' ' << std::is_move_assignable<tic>::value;
return 0;
}
And I can't understand why is the output true true
? I've tried to implement a constructor other than the default, and I wasn't able to use the generated default constructor, as specified, but in the case of copy assignment, I've implemented it and the class is still move-assignable and constructible.
std::is_move_assignable
only checks if the target class can be assigned from an rvalue of itself, which it can. A const lvalue reference can bind to rvalues, so as long as declval<tic&>() = declval<tic&&>()
compiles, std::is_move_assignable
returns true.
To be more explicit, you can set the move-assignment operator as deleted
. That way it participates in overload resolution and the move assignable check will fail.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.