C++中,模板构造函数是否会覆盖隐式复制构造函数?

7

一个模板构造函数(如下所示)是否会覆盖隐式复制构造函数?

template <class T>
struct Foo
{
    T data;

    // ...

    template <class U>
    Foo(const Foo<U> &other) : data((T)doSomethingWith(other.data)) {}

    // ...
};

如果是这样,如果通过值而不是常量引用传递other,它仍然会覆盖吗?
如果是这样,有没有任何方法可以避免显式定义复制构造函数?
3个回答

7
不,那不是拷贝构造函数。标准的12.8节([class.copy])要求:对于类X来说,如果它的非模板构造函数的第一个参数是X& 、const X& 、volatile X& 、或const volatile X&类型,并且没有其它参数或者所有其它参数都有默认值,则该构造函数为拷贝构造函数。编译器仍然会隐式生成一个默认构造函数。你可以通过以下方式显式地声明(需要C++11):
Foo(const Foo<T>&) = default;

2

一个模板构造函数(例如以下内容)是否会覆盖隐式复制构造函数?

不会。复制构造函数仍然会被隐式声明,并且会优先选择它而不是模板。

有没有任何方法可以避免显式定义复制构造函数?

没有。如果您不想要隐式的复制构造函数,那么您必须自己定义一个。


2
一个看起来像模板的构造函数或赋值运算符(包括默认构造函数/复制构造函数/移动构造函数/复制赋值运算符/移动赋值运算符),实际上并不是真正的[默认构造函数/复制构造函数/移动构造函数/复制赋值运算符/移动赋值运算符],也不能替换它或阻止它被隐式生成。

这个想法是正确的,但是你写的是错的。你的意思是“复制构造函数不会……”吗?那是错误的。你的意思是“模板复制构造函数不会……”吗?那是不存在的。 - Ben Voigt
@BenVoigt虽然我觉得之前已经很清楚了,但我尝试让它更准确——虽然说实话现在我觉得它更加令人困惑了。 - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接