gez*_*eza 32 c++ templates constructor copy-constructor language-lawyer
这是复制构造函数[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
};
Run Code Online (Sandbox Code Playgroud)
参见以下类似示例:
struct Foo {
Foo() = default;
template <typename T>
Foo(T &) {
printf("here\n");
}
};
int main() {
Foo a;
Foo b = a;
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,here将被打印。因此,似乎我的模板构造函数是一个复制构造函数,至少它的行为类似于一个(在通常调用复制构造函数的上下文中被调用)。
为什么文本中存在“非模板”要求?
Sto*_*ica 31
让我们将模板放置一秒钟。如果一个类未声明副本构造函数,则将生成一个隐式默认的副本构造函数。可以将其定义为已删除,但是仍然默认设置。
成员模板不是成员函数。仅在需要时才从中实例化成员。
那么,编译器如何仅从类定义中知道是否T = Foo将需要进行专业化?不行 但这正是需要决定如何处理隐式默认副本构造函数(AND move构造函数)的基础。变得混乱了。
最简单的方法是排除模板。无论如何,我们总会有一些拷贝构造函数,它在默认情况下会做正确的事情TM,并且由于不是从模板实例化的,所以它会受到重载解析的青睐。
lub*_*bgr 10
为什么文本中存在“非模板”要求?
鉴于两者不同,复制构造函数可以是模板。在存在复制构造函数模板的情况下,非复制构造函数如何不歧义?考虑一下:
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 &) {}
};
Run Code Online (Sandbox Code Playgroud)
此外,构造Foo从一个对象,它是一个不Foo可通过转化或普通的结构来实现的,但是允许复制结构从非Foo对象改变的概念复制到复制包括转化。但这可以通过现有方案(转换或非复制构造)实现。
在此示例中,将在此处打印。所以看来我的模板构造函数是一个复制构造函数
您显示的示例不会调用副本构造,而是一个普通的隐式构造。如果将构造函数模板更改为
template <typename T>
Foo(const T &) {
// ^^^^^
printf("here\n");
}
Run Code Online (Sandbox Code Playgroud)
然后Foo b = a;导致编译器生成的副本构造函数被调用。请注意,由编译器生成的副本ctor具有以下签名:
Foo(const Foo&);
Run Code Online (Sandbox Code Playgroud)
这需要增加一个const-qualifier到a在Foo b = a;。Foo(T&)代码段中的原始构造函数模板是更好的匹配,因为未const添加-qualifier。