一个templatised构造函数可以代表一个已删除的复制构造函数吗?

时间:2016-08-18 16:33:07

标签: c++

考虑

template<typename T>
struct Foo
{
    Foo(const Foo&) = delete;
    template <typename Y>
    Foo(const Foo<Y>&){}
};

模板构造函数的适当实例化是否代表复制构造函数?我知道它通常不会(因为复制构造函数不能是模板函数)但是在这里我删除了复制构造函数。

2 个答案:

答案 0 :(得分:4)

这里的问题是删除的函数仍然参与重载解析。所以给出了

Foo<int> a;
Foo<int> b{a};

可行的函数是已删除的复制构造函数和带有推导模板参数int的模板构造函数。作为非模板,删除的复制构造函数获胜。使用删除的功能会使程序格式不正确。

所以不,模板构造函数不能被实例化为复制相同类型对象的复制构造函数。

答案 1 :(得分:3)

不可以:重载​​决策始终首先考虑非模板化函数,当遇到delete d时,重载决策失败而不是考虑模板重载。

请允许我使用行

将默认构造函数引入您的类

Foo() = default;

然后,考虑两个变量

Foo<double> double_foo;
Foo<int> int_foo;

然后注意

    由于模板,
  1. Foo<int> bar(double_foo);被允许 由于Foo<int> bar(int_foo); d构造函数
  2. delete不被允许 如果您通过编写Foo<int> bar = Foo<int>();重新引入移动构造函数,则
  3. Foo(const Foo&&) = default; 将被允许。您需要在此使用=语法,因为Foo<int> bar(Foo<int>());是前向声明。
  4. 最后,你的断言“复制构造函数不能是模板函数”是不正确的。归功于@LightnessRacesInOrbit:

      

    C ++ 14 12.8.2“X类的非模板构造函数是一个副本   构造函数,如果它的第一个参数是X&amp;类型,const X&amp;,volatile   X&安培;或const volatile X&amp;,并且没有其他参数或   否则所有其他参数都有默认参数(8.3.6)。