Ten problem jest oparty na kodzie, który działa dla mnie na GCC-4.6, ale nie dla innego użytkownika z CLang-3.0, zarówno w trybie C++ 0x.Konflikt między konstruktorem kopiowania a konstruktorem przesyłania dalej
template <typename T>
struct MyBase
{
//protected:
T m;
template <typename Args...>
MyBase(Args&& ...x) : m(std::forward<Args>(x)...) {}
};
Przedmiotem MyBase
może przyjąć dowolną listę argumentów konstruktora, tak długo jak T
obsługuje że podpis budowlanej. Problem dotyczy funkcji specjalnych członków.
- IIUC, szablon konstruktora anuluje automatycznie zdefiniowany domyślny konstruktor. Jednakże, ponieważ szablon może przyjmować zero argumentów, będzie działał jako jawnie zdefiniowany domyślny konstruktor (tak długo, jak
T
jest domyślnie konstruktywny). - IIUC, określenie "zasady konstruowania kopii" klasy ignoruje szablony konstruktorów. Oznacza to, że w tym przypadku
MyBase
zyska automatycznie zdefiniowanego konstruktora kopiowania (o ile tylko można będzie kopiowaćT
), który będzie kanałować konstrukcję kopiiT
. - Zastosuj poprzedni krok również dla konstrukcji ruchu.
Więc jeśli przekazać MyBase<T> const &
jako jedyny argument konstruktora, który konstruktor zostanie wywołany, przekazywanie jeden lub niejawne kopiowanie jeden?
typedef std::vector<Int> int_vector;
typedef MyBase<int_vector> VB_type;
int_vector a{ 1, 3, 5 };
VB_type b{ a };
VB_type c{ b }; // which constructor gets called
Problemem mojego użytkownika było użycie tego jako klasy bazowej. Kompilator skarżył się, że jego klasa nie może zsyntetyzować automatycznie zdefiniowanego konstruktora kopii, ponieważ nie może znaleźć dopasowania do szablonu konstruktora klasy podstawowej. Czy nie powinien wywoływać automatycznego konstruktora kopiowania dla swojego własnego automatycznego konstruktora kopiowania? Czy CLang jest błędny z powodu konfliktu?
Interesujące pytanie. Polecam wykonanie sscce (zobacz http://sscce.org/), która działa w GCC i nie działa w CLang, aby pomóc nam lepiej zrozumieć problem i odtworzyć go samodzielnie. Podaj nam dokładny komunikat o błędzie z CLang. –
W rzeczywistości wersja gcc stosunkowo blisko głowy (od 20120202) również nie akceptuje tego kodu. Wygląda na to, że konstruktor przekazujący jest odbierany nawet dla kopii. Nie jestem do końca pewien, dlaczego tak jest. Nie jest to związane z "jednolitą składnią inicjalizacji": nawet przy użyciu nawiasów dla ostatniej deklaracji nie kompiluje się. –
Mój kod jest czymś, co napisałem dekadę temu dla Boost i zaktualizowany dla C++ 11 w zeszłym tygodniu. Nie wiem, jak pracować z całym systemem Boost, ale możesz przejrzeć [moje zmiany] (https://svn.boost.org/trac/boost/changeset/76982) i [obecny stan] (http : //svn.boost.org/svn/boost/trunk/boost/utility/base_from_member.hpp) pliku (w wersji 77031 w tym piśmie). – CTMacUser