這裏的機制很好地解釋了: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