考虑以下计划:
#include <iostream>
struct Test
{
int a;
Test() : a(3)
{ }
Test(const Test& t...)
{
std::cout<<"Copy constructor called\n";
a=t.a;
}
int get_a()
{
return a;
}
~Test()
{
std::cout<<"Destructor is called\n";
}
};
int main()
{
Test t;
Test* t1=new Test(t);
std::cout<<t.get_a()<<'\n';
std::cout<<t1->get_a()<<'\n';
delete t1;
}
密切观察复制构造函数参数中的三个点 当我尝试这个程序时,我真的很惊讶。有什么用?这是什么意思?
语言规范对此有何看法?
我知道三个点用于表示可变参数函数中的变长参数
像printf()
和scanf()
等,以及C99引入的可变参数宏。在C ++中,如果我没有错,它们将用于可变参数模板
这段代码是否形成良好?这个可变参数构造函数是否可以使用任意数量的参数?
它编译&amp;在g ++ 4.8.1&amp; MSVS 2010.
答案 0 :(得分:5)
8.3.5
[dcl.fct] 部分中的标准草案说, ...
与...
同义,除非...
是摘要的一部分 - 声明者(强调我的):
[...]如果参数声明子句以省略号终止 或函数参数包(14.5.3),参数的数量 等于或大于没有的参数数量 默认参数,不是函数参数包。其中的 语法正确,“......”不是一部分 abstract-declarator,“,...”与“......”同义。。[...]
所以它是一个variadic function,据我所知,没有其他参数,这也是一个有效的复制构造函数,来自12.8
[class.copy] 部分:
类X的非模板构造函数是复制构造函数(如果是) 第一个参数是X&amp;类型,const X&amp;,volatile X&amp;或const volatile X&amp;,并且没有其他参数或其他所有参数 参数有默认参数(8.3.6)。
并且这个说明说椭圆不是参数:
void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow // a parameter with a default argument
由上面的规范性文本支持:
如果参数声明子句以省略号[...]
终止
注意,因为有人要求 abstract-declarator 是没有标识符的声明符。
答案 1 :(得分:5)
有什么用?这是什么意思?
是的,它引入了一种可变函数。
在C ++中如果我没有错,它们将用在可变参数模板中。
语法和语义不同。它是“C风格”的可变参数函数,而不是可变参数模板函数。此外,复制构造函数不能是模板函数。
X类的非模板构造函数是复制构造函数,如果它的 第一个参数是X&amp;类型,const X&amp;,volatile X&amp;或const volatile X&amp;和没有其他参数或其他所有参数 参数有默认参数(8.3.6)。
最终草案中的§12.8.2(强调我的)
这段代码是否形成良好?这个可变参数构造函数是否可以使用任意数量的参数?
如果省略号包含参数,则它不再是复制构造函数,而是一个简单的构造函数。如果没有,那么它是一个有效的复制构造函数。
X(const X&, int = 1, double = 5); // copy-ctor
X(const X&, int = 1, double); // constructor