В чем смысл эллипсов в конструкторе копирования?

Рассмотрим следующую программу:

#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. В С++, если я не ошибаюсь, они используются в вариативных шаблонах.
Является ли этот код хорошо сформированным? Является ли этот конструктор вариационной копии, который может принимать любое количество аргументов?

Он компилируется и работает отлично на g++ 4.8.1 и MSVS 2010.

Ответы

Ответ 1

В стандарте в разделе 8.3.5 [dcl.fct] указано, что , ... является синонимом ..., если только ... не является частью абстрактного-декларатора (выделение мое):

[...] Если предложение параметра-объявления заканчивается с помощью многоточия или пакет параметров функций (14.5.3), количество аргументов должно быть равно или больше, чем количество параметров, которые не имеют аргумент по умолчанию и не являются пачками параметров. Где синтаксически правильно и где "..." не является частью abstract-declarator, ",..." является синонимом "..." . [...]

Так что это вариационная функция, и насколько я могу сказать без дополнительных аргументов, это также допустимый конструктор копирования, из раздела 12.8 [class.copy ]:

Конструктор без шаблона для класса X является конструктором копирования, если его первый параметр имеет тип X &, const X &, изменчивый 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

который подкреплен нормативным текстом, который гласит:

Если предложение parameter-declaration завершается с помощью многоточия [...]

Обратите внимание, что с запросом абстрактного-декларатора является декларатором без идентификатора.

Ответ 2

Какая польза от этого? Что это значит?

Да, он вводит вариационную функцию.

В С++ Если я не ошибаюсь, они используются в вариативных шаблонах.

Синтаксис и семантика различны. Это вариационная функция C-стиля, а не вариационная функция шаблона. Более того, конструктор копирования не может быть функцией шаблона.

Конструктор не шаблон для класса X является конструктором , если его  первый параметр имеет тип X &, const X &, изменчивый X & или const volatile  X &, и либо нет других параметров, либо все остальные  параметры имеют аргументы по умолчанию (8.3.6).

В §12.8.2 в окончательном проекте (акцент мой)

Является ли этот код хорошо сформированным? Является ли этот конструктор вариационной копии, который может принимать любое количество аргументов?

Если эллипсис содержит параметры, он больше не является конструктором копирования, а простым конструктором. Если нет, то это допустимый конструктор копирования.

 X(const X&, int = 1, double = 5); // copy-ctor
 X(const X&, int = 1, double); // constructor