Given następujący przykład:Mieszanie dziedziczone konstruktor z klasy bazowej z niestandardowym construcutor
struct tag1 { };
struct tag2 { };
template<typename T>
class Base {
public:
Base(T /*value*/) { }
Base(tag1) { }
};
template<>
class Base<void> {
public:
Base() { }
Base(tag1) { }
};
template<typename T = void>
class MyClass : public Base<T> {
public:
using Base<T>::Base;
MyClass(tag2) : Base<T>(tag1{}) { }
};
int main() {
{
MyClass<> defaultConstructible;
MyClass<> tagConstructible(tag2{});
}
{
MyClass<int> valueConstructible(0);
MyClass<int> tagConstructible(tag2{});
}
}
Klasa MyClass
mogą być programowane z wszelkich typów, powinien być domyślny constructible gdy typ T
równa void
, inaczej jest konstruktywny z typu T
, jak napisano w funkcji main
.
Używam klasy bazowej zależnej od parametru, aby uzyskać to zachowanie (poprzez użycie konstruktora klasy bazowej).
Potrzebuję również dodać konstruktory do hierarchii klas, które akceptują inne parametry, jak widać w źródłowym przykładzie (znaczniki structs).
Czy można to zrobić bez deklarowania wszystkich konstruktorów w tej samej klasie? Ponieważ zmieszanie konstruktorów nadklasy z niestandardowymi te dadzą się następujący komunikat o błędzie:
main.cpp: In function 'int main()':
main.cpp:30:15: error: no matching function for call to 'MyClass<>::MyClass()'
MyClass<> defaultConstructible;
^~~~~~~~~~~~~~~~~~~~
main.cpp:22:18: note: candidate: MyClass<>::MyClass(tag1)
using Base<T>::Base;
^~~~
main.cpp:22:18: note: candidate expects 1 argument, 0 provided
main.cpp:25:3: note: candidate: MyClass<T>::MyClass(tag2) [with T = void]
MyClass(tag2) : Base<T>(tag1{}) { }
^~~~~~~
main.cpp:25:3: note: candidate expects 1 argument, 0 provided
main.cpp:20:7: note: candidate: constexpr MyClass<>::MyClass(const MyClass<>&)
class MyClass : public Base<T> {
^~~~~~~
main.cpp:20:7: note: candidate expects 1 argument, 0 provided
main.cpp:20:7: note: candidate: constexpr MyClass<>::MyClass(MyClass<>&&)
main.cpp:20:7: note: candidate expects 1 argument, 0 provided
Jak tylko wprowadzisz sparametryzowany konstruktor dla 'MyClass', żaden domyślny konstruktor nie zostanie wygenerowany przez kompilator, więc czego właściwie się spodziewasz? –
Dobra rada, spodziewam się, że klasa 'MyClass' będzie domyślnie konstruktywna, gdy parametr' T' jest nieważny, ponieważ używam go z klasy bazowej (która jest jawnie tam zadeklarowana). –
_ "Oczekuję, że klasa MyClass będzie domyślna, gdy parametr T jest nieważny, ponieważ używam go z klasy bazowej" _ To zachowanie dedukcji nie jest _ "dziedziczone" _. –