繁体   English   中英

为什么标准不将模板构造函数视为复制构造函数?

[英]Why doesn't the standard consider a template constructor as a copy constructor?

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

如果X类的第一个参数是X&,const X&,volatile X&或const volatile X&,并且没有其他参数或者所有其他参数都有默认参数([dcl。],则X类的非模板构造函数是一个复制构造函数。 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 所以我的模板构造函数似乎是一个复制构造函数,至少它表现得像一个(它在通常调用复制构造函数的上下文中调用)。

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

让模板放在一边一秒钟。 如果类未声明复制构造函数,则会生成隐式默认值。 它可能被定义为已删除,但它仍然是默认的。

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

那么编译器如何才能从类定义中知道是否需要使用T = Foo 它不能。 但正是在这个问题上,它需要根据如何处理隐式默认复制构造函数(AND移动构造函数)的潜在需求做出决定。 那变得凌乱。

最简单的方法是排除模板。 无论如何,我们总是会有一些复制构造函数,它默认会执行正确的TM ,并且会被重载解析所支持,因为它不是从模板中实例化的。

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

鉴于它是不同的,复制构造函数可以是模板。 如果存在复制构造函数模板,非复制构造函数怎么可能不明确? 考虑一下:

struct Foo {
   // ctor template: clearly useful and necessary
   template <typename T>
      Foo(const T&) {}

   // copy ctor: same signature! can't work
   template <typename T>
      Foo(const T &) {}
};

此外,构造Foo从一个对象,该对象是不是一个Foo可以通过转化或普通的结构来实现的,但是允许从一个非复制结构Foo对象改变复制的概念来复制包括转换 但这已经可以用现有方案(转换或非复制构造)实现。

在此示例中,将打印此处。 所以我的模板构造函数似乎是一个复制构造函数

您显示的示例不会调用复制构造,而是调用普通的隐式构造。 如果您将构造函数模板更改为

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

那么Foo b = a; 导致编译器生成的复制构造函数被调用。 请注意,编译器生成的copy ctor具有以下签名:

Foo(const Foo&);

这需要增加一个const -qualifier到aFoo b = a; 您的代码段中的原始构造函数模板Foo(T&)是更好的匹配,因为没有添加const -qualifier。

复制构造函数的形式为X(X&)或(X const&),如果您没有自己声明,它将由编译器为您提供。 如果您使用模板类,非模板可能会因此而出现问题。

假设有一个模板类,它有一个模板复制构造函数。 问题是,当您使用具有相同模板类型的此类的另一个实例来实例化该类时,将不会调用模板复制构造函数。

问题不在于您的复制构造函数模板不匹配。 问题是隐式复制构造函数不是函数模板,并且在涉及重载解析时,非模板优先于模板特化。

来源: 模板类上的C ++模板复制构造函数

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM