首页 > 解决方案 > 为什么标准不将模板构造函数视为复制构造函数?

问题描述

这是复制构造函数的定义,[class.copy.ctor/1]

类 X 的非模板构造函数是复制构造函数,如果它的第一个参数是 X&、const X&、volatile X& 或 const volatile X& 类型,并且没有其他参数,或者所有其他参数都有默认参数([dcl. fct.default])。

为什么标准将模板排除为复制构造函数?

在这个简单的例子中,两个构造函数都是拷贝构造函数:

struct Foo {
    Foo(const Foo &); // copy constructor
    Foo(Foo &);       // copy constructor
};

看这个类似的例子:

struct Foo {
     Foo() = default;

     template <typename T>
     Foo(T &) {
         printf("here\n");
     }
};

int main() {
    Foo a;
    Foo b = a;
}

在本例中,here将被打印。所以看起来我的模板构造函数是一个复制构造函数,至少它的行为就像一个(在通常调用复制构造函数的上下文中调用它)。

为什么文本中有“非模板”要求?

标签: c++templatesconstructorlanguage-lawyercopy-constructor

解决方案


让我们暂时搁置模板。如果一个类没有声明复制构造函数,则会生成一个隐式默认的构造函数。它可能被定义为已删除,但它仍然是默认的。

成员模板不是成员函数。成员仅在需要时从它实例化。

那么编译器如何仅从类定义中知道是否T = Foo需要专门化 with 呢?它不能。但这正是它需要决定如何处理隐式默认复制构造函数(AND 移动构造函数)的潜在需求的基础。这变得混乱。

最简单的方法是排除模板。无论如何,我们总会有一些复制构造函数,默认情况下它会做正确的事情,并且会受到重载决议的青睐,因为它不是从模板实例化的


推荐阅读