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