考虑
template<typename T>
struct Foo
{
Foo(const Foo&) = delete;
template <typename Y>
Foo(const Foo<Y>&){}
};
模板构造函数的适当实例化是否代表复制构造函数?我知道它通常不会(因为复制构造函数不能是模板函数)但是在这里我删除了复制构造函数。
答案 0 :(得分:4)
这里的问题是删除的函数仍然参与重载解析。所以给出了
Foo<int> a;
Foo<int> b{a};
可行的函数是已删除的复制构造函数和带有推导模板参数int
的模板构造函数。作为非模板,删除的复制构造函数获胜。使用删除的功能会使程序格式不正确。
所以不,模板构造函数不能被实例化为复制相同类型对象的复制构造函数。
答案 1 :(得分:3)
不可以:重载决策始终首先考虑非模板化函数,当遇到delete
d时,重载决策失败而不是考虑模板重载。
请允许我使用行
将默认构造函数引入您的类 Foo() = default;
然后,考虑两个变量
Foo<double> double_foo;
Foo<int> int_foo;
然后注意
Foo<int> bar(double_foo);
被允许
由于Foo<int> bar(int_foo);
d构造函数delete
不被允许
如果您通过编写Foo<int> bar = Foo<int>();
重新引入移动构造函数,则Foo(const Foo&&) = default;
将被允许。您需要在此使用=
语法,因为Foo<int> bar(Foo<int>());
是前向声明。最后,你的断言“复制构造函数不能是模板函数”是不正确的。归功于@LightnessRacesInOrbit:
C ++ 14 12.8.2“X类的非模板构造函数是一个副本 构造函数,如果它的第一个参数是X&amp;类型,const X&amp;,volatile X&安培;或const volatile X&amp;,并且没有其他参数或 否则所有其他参数都有默认参数(8.3.6)。