Почему конструктор копирования не вызывается?

Извините за чрезмерно двусмысленный заголовок. (Из-за отсутствия моих навыков английского языка). Пожалуйста, предложите лучший заголовок.

Пожалуйста, рассмотрите следующий код.

struct A {
typedef std::vector<double> State;

//  template <class... Args>
//  A(Args... args)
//      : a(args...)
//  {}

template <class... Args>
A(Args&&... args)
: a(std::forward<Args>(args)...)
{}

A(const A&) = default;
A(A&&) = default;

State a;
};

int main(){

A a(3,2);
A b = a; // This line triggers an error!!
}

Gcc 4.8.0 не удалось скомпилировать его с сообщением об ошибке
error: no matching function for call to 'std::vector<double>::vector(A&)' : a(std::forward<Args>(args)...),

Я не могу понять, почему этот код неправильный. На мой взгляд, компилятор должен вызывать конструктор копирования в строке A b = a;,

Однако, если я заменю конструктор закомментированным (который просто принимает значения). Это компилируется. Кроме того, теперь строки для конструкторов копирования (и перемещения) по умолчанию не нужны.
Что здесь происходит?

10

Решение

В C ++ 11 наличие компилятора автоматически выводит параметры шаблона (как вы должны делать с шаблонным конструктором) и применяет && к типу создает универсальную ссылку, которая сопоставляет любой тип с любой квалификацией cv, будь то ссылка lvalue или rvalue.

Так что в вашем случае вы проходите в A, и поэтому Args...знак равноA &, Args &&...знак равноA & &&, который A & благодаря правилам свертывания ссылок, что лучше, чем const A &, поскольку компилятору не нужно добавлять константу в неконстантную переменную.

9

Другие решения

Я думаю, что в этом случае конструктор шаблона лучше подходит, потому что он принимает неконстантное значение. если вы измените a в const это вызвало бы конструктор копирования …

const A a(3,2);
A b = a;
3

По вопросам рекламы [email protected]