这里的机制很好地解释了:Template "copy constructor" does not prevent compiler-generated move constructor,但我想更好地理解为什么这样做。我明白即使任何其他构造函数是由程序员编写的,也不会生成移动构造函数,因为它表明构造对象不是微不足道的,自动生成的构造函数可能是错误的。那么为什么具有与复制构造函数相同签名的模板化构造函数不是简单的命名复制构造函数?为什么编译器在存在模板构造函数时会生成复制/移动构造函数?
例子:
class Person {
public:
template<typename T>
Person(T&& t) : s(std::forward<T>(t)) {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
Person(int n) {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
// No need to declare copy/move constructors as compiler will do this implicitly
// Templated constructor does not inhibit it.
//Person(const Person&) = default;
//Person(Person&&) = default;
private:
std::string s;
};
然后:
Person p("asd"); // OK!
//Person p4(p); // error as Person(T&&) is a better match
,如果我做p
常量:
const Person p("asd");
Person p4(p); // thats ok, generator constructor is a better match
,但如果我直接删除,甚至有转移构造函数:
Person(Person&&) = delete;
然后禁止自动生成构造函数。
“*我明白,即使任何其他构造函数是由程序员编写的,也不会生成移动构造函数*”这不是事实。只有存在复制构造函数/赋值才能防止生成移动构造函数。 –
@NicolBolas谢谢,我在Effective Modern C++中查找了第17项,并且还移动了构造函数/赋值运算符和析构函数,以防止生成移动构造函数或赋值运算符。 – mike