12

Moje rozumienie o C++ niejawny kopii konstruktora jest podobna doracjonalne uzasadnienie C++ ukrytego kopiowania i przenoszenia konstruktora?

T(T const& x) : 
    base1(x), base2(x) ... , 
    var1(x.var1), var2(x.var2)... 
{} 

Move konstruktorze, skopiuj & przypisanie ruch następuje również podobny wzór.

Dlaczego nie zdefiniowano go w podobny sposób?

T(T const& x) : 
    base1(static_cast<base1 const&>(x)), 
    base2(static_cast<base2 const&>(x)) ... , 
    var1(x.var1), var2(x.var2)... 
{} 

Przykład

miałem klasy, który miał ukryte kopiowania/operatora konstruktor/przydziału, jak również niektóre konwersji konstruktorów. Delegowałem pracę do pewnej klasy implementacji.

class common_work //common implementation of many work like classes 
{ 
    common_work(common_work const&) = default; 
    common_work(common_work&&) = default;// ... implicit constructors work for me. 
    //a forwarding constructor which can take many work like objects 
    template<class T, enable_if<work_like<T> > > 
    common_work(T&& x) { ... } 
}; 
class work1 //one of the implementation 
{ 
    work1(work1 const&) = default; 
    work1(work1&&) = default; ... 
    common_work impl_; 
}; 

To dobrze, jak work1 kopii/konstruktory ruch dzwoni konstruktora kopiowania/dla common_work i przesyłanie konstruktora użyto innych konstruktorów [niepokazane kodu, który przetwarza] z innego rodzaju work.

Potem pomyślałem o odziedziczeniu work1 z common_work dla EBO i innych powodów. Tak więc nowy work1 klasa wyglądało

class work1 : private common_work 
{ 
    work1(work1 const&) = default; 
    work1(work1&&) = default; ... 
}; 

Ale jak work1 jest klasą work_like nagle konstruktor spedycja był coraz lepszy mecz, jako konstruktor kopia/ruch dla common_work wymaga static_cast z pochodzącą do bazy.

UWAGA:

  • Jest podobny rodzaj przykład podany przez Scott Meyers, gdzie budowa kopia wyzwala spedycja konstruktor jako konstruktora kopii wymaga const Ponadto podczas przesyłania konstruktora wymaga żadnego. Ale myślę, że ten problem powstaje z powodu niewłaściwego projektowania klas, podczas gdy problem tutaj wynika z tego, że argument przekazany do klasy bazowej podczas niejawnego kopiowania/przenoszenia nie jest dokładnie dopasowany.
  • Nie mogę zapisać uniwersalnego przekierowania/przypisania i usunąć niejawne, ponieważ usunięte funkcje uczestniczą również w przeciążeniu i powodują błąd, jeśli są dokładnie dopasowane.
  • Rozwiązaniem, które obecnie mam, jest utworzenie common_work jako CRTP, tj. Wyprowadzony typ klasy przekazany jako argument szablonu, a w konstruktorze przekazującym filtrowanie go jako enable_if<and_<work_like<T>,not_<is_same<T,Derived> > > >. W przeciwnym razie muszę ręcznie napisać copy/move constructor/assignment dla work1 i static_cast do klas bazowych jawnie, co jest błędne, podatne na błędy i zagrożenie konserwacyjne.
+0

Być może można to obejść, wzmacniając ograniczenie SFINAE, tak aby odrzucił "T", które pochodzą od 'common_work'? –

+0

To właśnie teraz robię. Spójrz na 3 punkt w sekcji UWAGA. Chociaż nie powinno to być 'is_same ', raczej 'is_same , Derived>' – abir

+0

OK, przepraszam. Nie czytałem ostatniej notatki :) –

Odpowiedz

1

Ten problem został omówiony na stronie błędów systemu MSVC++ kilka lat temu (więc jeśli nie jest jeszcze naprawiony, jest to znany problem w MSVC++). Standard mówi

  • ... podstawa lub członkiem jest bezpośrednim zainicjowany z odpowiednią zasadą lub członek x.

zrobiłem testować różne kompilatory kiedy czytam wypełnienie i wysłanie, a wszystkie z nich „magicznie lanego”. Standard wydaje się być cichy na samych detalach (także o kategorii wartości i kwalifikacjach c/v) i po prostu mówi "z odpowiednią podstawą ... z x", co IMO ma o wiele większy sens, jeśli weźmiesz to pod uwagę "bez x, ale z odpowiednią podstawą ... z x", a nie, że przekazujesz mu cały obiekt (nawet posunąłbym się do stwierdzenia, że ​​w ten sposób może to być sensowne).

+0

Należy zauważyć, że jawnie domyślne specjalne funkcje członków nie są jeszcze zaimplementowane w MSVC (chociaż powiedzieli, że dostaną je wkrótce w 2013 RTM). –

Powiązane problemy