What is the meaning of ellipses in a copy constructor?
Asked Answered
J

2

15

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.

Joannajoanne answered 1/10, 2015 at 18:9 Comment(5)
Same as Test(const Test& t, ...) (note the comma)Kerb
Any constructor that can be called with one value of the type itself and takes it by reference is a possible copy constructor. The fact that optional further arguments may be supplied is immaterial.Polysepalous
@PiotrSkotnicki: So, why comma is not necessary?Joannajoanne
@PravasiMeet I think the language spec explicitly allows this. I'm not sure why they explicitly allow this, but they do.Sumach
I updated my answer, explaining what an abstract-declarator is.Justly
J
5

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.

Justly answered 1/10, 2015 at 18:28 Comment(1)
Note the first rule I quote is what allows for the infamous six dots.Justly
S
5

What is the use of it? What does it mean?

Yes, it introduces a variadic function.

In C++ If I am not wrong they are used in variadic templates.

The syntax and semantics are different. It's a "C-style" variadic function, not a variadic template function. A copy constructor, moreover, cannot be a template function.

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).

Per §12.8.2 in the final draft (emphasis mine)

Is this code well formed? Is this variadic copy constructor that can take any number of arguments?

If the ellipsis contains parameters, it is no more a copy constructor but a simple constructor. If there aren't, then it is a valid copy constructor.

 X(const X&, int = 1, double = 5); // copy-ctor
 X(const X&, int = 1, double); // constructor
Salamander answered 1/10, 2015 at 19:11 Comment(1)
So can I say that the progam in this link doesn't have copy constrctor because it uses no default arguments. ideone.com/VuNTU5Joannajoanne

© 2022 - 2024 — McMap. All rights reserved.