2012-09-11 78 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