給定以下代碼,Foo是否具有拷貝構造函數?將Foo與STL容器一起使用是否安全?模板拷貝構造函數
class Foo
{
public:
Foo() {}
template <typename T>
Foo(const T&) {}
};
給定以下代碼,Foo是否具有拷貝構造函數?將Foo與STL容器一起使用是否安全?模板拷貝構造函數
class Foo
{
public:
Foo() {}
template <typename T>
Foo(const T&) {}
};
標準明確地說,一個拷貝構造是一個非模板化的構造,需要一個參考相同類型的可能常量揮發性對象。在上面的代碼中,您有一個轉換但不是複製構造函數(即它將用於所有的但副本,其中隱式聲明的構造函數將被使用)。
Foo
有複製構造函數嗎?
是的,隱式聲明/定義的複製構造函數。
使用
Foo
與標準庫容器安全嗎?
隨着Foo
當前定義它,但在一般情況下,這取決於Foo
有哪些成員,以及是否隱含定義拷貝構造函數管理這些正確。
Foo
有一個編譯器生成的拷貝構造函數,它不能被你提供的模板轉換構造函數替換。
Foo f0;
Foo f1(f0); // calls compiler-synthesized copy constructor
Foo f2(42); // calls template conversion constructor with T=int
這似乎並不真正調用複製構造函數。 ://stackoverflow.com/questions/11037644/how-do-i-get-the-copy-constructor-called-over-a-variadic-constructor –
根據標準,一個拷貝構造函數必須是下列簽名之一:
Foo(Foo &);
Foo(Foo const &);
Foo(Foo volatile &);
Foo(Foo const volatile &);
Foo(Foo&, int = 0,);
Foo(Foo&, int = 0, float = 1.0); //i.e the rest (after first) of the
//parameter(s) must have default values!
因爲在你的代碼模板的構造函數不匹配與上述任何形式,即不是副本 -constructor。
也可以有默認參數 – FrozenHeart
@NikitaTrophimov:是的,也是如此。 – Nawaz
如果這是在模板'Foo(const Foo&)= delete;'之前聲明會發生什麼?該類現在是否沒有拷貝構造函數,或者模板是否被調用? – orlp
如果複製構造函數被刪除,那麼這個類沒有一個。 ;-) –
@nightcracker然後沒有拷貝構造函數,編譯器給出錯誤(除非你有一個表達式,例如可以使用移動拷貝構造函數)。關鍵是複製構造函數是*非模板*。 – juanchopanza