考虑以下程序:
#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 ++中,如果我没记错的话,它们可用于可变参数模板中。
该代码格式正确吗?这个可变参数复制构造函数可以接受任意数量的参数吗?
它可以在g ++ 4.8.1和MSVS 2010上编译并正常运行。
在节中的标准草案8.3.5
[dcl.fct]说, ...
是同义词...
,除非...
是抽象的说明符(部分重点矿山):
[...]如果参数声明子句以省略号或函数参数包(14.5.3)结尾,则参数数量应等于或大于没有默认参数的参数数量,并且不是功能参数包。在语法上正确,并且“ ...”不是抽象声明符的一部分时,“,...”与“ ...”同义。[...]
因此,这是一个可变参数函数,据我所知,在没有附加参数的情况下,这也是有效的复制构造函数,来自12.8
[class.copy]部分:
如果类X的非模板构造函数的第一个参数为X&,const X&,volatile X&或const volatile X&类型,并且没有其他参数,或者所有其他参数都具有默认参数(8.3.6),则它是复制构造函数。 )。
这个注释说椭圆不是参数:
void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow // a parameter with a default argument
上面的规范性文本提供了支持:
如果参数声明子句以省略号[...]结尾
注意,由于有人要求抽象声明符是没有标识符的声明符。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句