2013-06-06 13 views
10

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

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

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

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

ответ

9

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

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

+1

О, я вижу. Спасибо за четкое объяснение. :) – Sungmin

3

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

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

Спасибо, если я добавлю еще один конструктор копии 'A (A &) = default'. Он прекрасно компилируется. :) – Sungmin

Смежные вопросы