2013-06-06 14 views
10

Przepraszamy za zbyt dwuznaczny tytuł (z powodu braku moich umiejętności językowych). Zaproponuj lepszy tytuł.Dlaczego kopiowanie konstruktora nie jest wywoływane?

Proszę wziąć pod uwagę następujący kod.

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 nie skompilować z komunikatem o błędzie error: no matching function for call to 'std::vector<double>::vector(A&)' : a(std::forward<Args>(args)...).

Nie mogę zrozumieć, dlaczego ten kod jest nieprawidłowy. Moim zdaniem, kompilator powinien wywołać konstruktora kopii w linii A b = a;.

Jednak jeśli zamieniam konstruktor na skomentowany (który po prostu przyjmuje wartości). Kompiluje. Co więcej, teraz linie dla domyślnych konstruktorów kopiowania (i przenoszenia) nie są potrzebne. Co się tutaj dzieje?

Odpowiedz

9

w C++ 11 o kompilator automatycznie wywnioskować parametrów szablonu (jak trzeba zrobić z matrycy konstruktora) i stosując && do rodzaju tworzy odniesienie uniwersalne, które pasuje do dowolnego typu z dowolną kwalifikacją cv, niezależnie od tego, czy jest to wartość l, czy też wartość r.

Więc w twoim przypadku jesteś przejazdem w A i dlatego Args... = A &, Args &&... = A & &&, który jest A & dzięki zasad referencyjnych zawaleniem, co jest lepsze dopasowanie niż const A &, ponieważ kompilator nie dodać stałą do zmiennej stałej.

+1

Och, rozumiem. Dzięki za jasne wyjaśnienie. :) – Sungmin

3

Myślę, że w tym przypadku konstruktor szablonu jest lepiej dopasowany, ponieważ przyjmuje wartość inną niż const. jeśli zmienisz a do const byłoby wywołać konstruktor kopiujący ...

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

Dziękuję, jeśli dodaję innego konstruktora kopiowania 'A (A &) = default'. Kompiluje się dobrze. :) – Sungmin

Powiązane problemy