2012-09-11 119 views
8

給定以下代碼,Foo是否具有拷貝構造函數?將Foo與STL容器一起使用是否安全?模板拷貝構造函數

class Foo 
{ 
public: 
    Foo() {} 

    template <typename T> 
    Foo(const T&) {} 
}; 

回答

10

標準明確地說,一個拷貝構造是一個非模板化的構造,需要一個參考相同類型的可能常量揮發性對象。在上面的代碼中,您有一個轉換但不是複製構造函數(即它將用於所有的副本,其中隱式聲明的構造函數將被使用)。

Foo有複製構造函數嗎?

是的,隱式聲明/定義的複製構造函數。

使用Foo與標準庫容器安全嗎?

隨着Foo當前定義它,但在一般情況下,這取決於Foo有哪些成員,以及是否隱含定義拷貝構造函數管理這些正確。

+0

如果這是在模板'Foo(const Foo&)= delete;'之前聲明會發生什麼?該類現在是否沒有拷貝構造函數,或者模板是否被調用? – orlp

+1

如果複製構造函數被刪除,那麼這個類沒有一個。 ;-) –

+0

@nightcracker然後沒有拷貝構造函數,編譯器給出錯誤(除非你有一個表達式,例如可以使用移動拷貝構造函數)。關鍵是複製構造函數是*非模板*。 – juanchopanza

1

Foo有一個編譯器生成的拷貝構造函數,它不能被你提供的模板轉換構造函數替換。

Foo f0; 
Foo f1(f0); // calls compiler-synthesized copy constructor 
Foo f2(42); // calls template conversion constructor with T=int 
+0

這似乎並不真正調用複製構造函數。 ://stackoverflow.com/questions/11037644/how-do-i-get-the-copy-constructor-called-over-a-variadic-constructor –

4

根據標準,一個拷貝構造函數必須是下列簽名之一:

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。

+1

也可以有默認參數 – FrozenHeart

+0

@NikitaTrophimov:是的,也是如此。 – Nawaz