在The C++ Programming Language 4th edition
中,作者说
•如果程序员声明了某个类的复制操作,移动操作或析构函数,则不会为该类生成任何复制操作,移动操作或析构函数。
•如果程序员为类声明任何构造函数,则不会为该类生成默认构造函数。
因此,我试图在实际中看到这一点,所以我实现了本书中的一个示例,一个具有std::vector
成员的简单类,一个默认构造函数的实现和一个复制赋值运算符。
#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;
}
我不明白为什么输出
true true
?我尝试实现默认构造函数以外的其他构造函数,但无法使用指定的生成的默认构造函数,但是在复制分配的情况下,我已经实现了它,并且该类仍可移动分配并且可以构建。
答案 0 :(得分:5)
std::is_move_assignable
仅检查是否可以从自身的右值分配目标类。 const左值引用可以绑定到右值,因此只要declval<tic&>() = declval<tic&&>()
进行编译,std::is_move_assignable
就会返回true。
为了更加明确,可以将移动分配运算符设置为deleted
。这样,它就可以参与过载解析,并且可分配移动检查将失败。