Consider the following program:
#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;
}
Closely observe the three dots in parameter of copy constructor I was really surprised when I tried this program. What is the use of it? What does it mean?
What the language specification says about this?
I know that three dots are used to represent variable length arguments in variadic functions
like printf()
and scanf()
etc and also variadic macros introduced by C99. In C++, if I am not wrong, they are used in variadic templates.
Is this code well formed? Is this variadic copy constructor that can take any number of arguments?
It compiles & runs fine on g++ 4.8.1 & MSVS 2010.
In the C programming language, an ellipsis is used to represent a variable number of parameters to a function. For example: int printf( const char* format, ... ); The above function in C could then be called with different types and numbers of parameters such as: printf("numbers %i %i %i", 5, 10, 15);
Ellipsis in C++ allows the function to accept an indeterminate number of arguments. It is also known as the variable argument list. Ellipsis tells the compiler to not check the type and number of parameters the function should accept which allows the user to pass the variable argument list.
It takes two parameters: the va_list and the last specified non-ellipsis parameter. To get each ellipsis parameter, the va_arg macro requires the va_list object ( list ) and the type of the last non-ellipsis parameter. Our code example contains only one specified parameter, num of type int.
Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.
The draft standard in section 8.3.5
[dcl.fct] says , ...
is synonymous with ...
unless ...
is part of abstract-declarator (emphasis mine):
[...]If the parameter-declaration-clause terminates with an ellipsis or a function parameter pack (14.5.3), the number of arguments shall be equal to or greater than the number of parameters that do not have a default argument and are not function parameter packs. Where syntactically correct and where “...” is not part of an abstract-declarator, “, ...” is synonymous with “...”.[...]
So it is a variadic function and as far as I can tell without additional arguments this is also a valid copy constructor, from section 12.8
[class.copy]:
A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6).
and this note says that ellipses are not parameters:
void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow // a parameter with a default argument
which is backed up by the normative text above which says:
If the parameter-declaration-clause terminates with an ellipsis[...]
Note, since it was asked an abstract-declarator is a declarator without an identifier.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With