【发布时间】:2017-07-20 23:34:53
【问题描述】:
这里很好地解释了这个机制: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:
const Person p("asd");
Person p4(p); // thats ok, generator constructor is a better match
但如果我使用以下命令显式删除移动构造函数:
Person(Person&&) = delete;
然后禁止自动生成构造函数。
【问题讨论】:
-
"我知道即使程序员编写了任何其他构造函数,也不会生成移动构造函数" 这不是真的。只有存在复制构造函数/赋值才能阻止移动构造函数的生成。
-
@NicolBolas 谢谢,我在 Effective Modern C++ 中查找了第 17 项,并且移动构造函数/赋值运算符和析构函数阻止生成移动构造函数或赋值运算符。