Im Grunde möchte ich also eine Klasse definieren, die von einer beliebigen Anzahl von Klassen erbt und eine Methode enthält, die die überladene Methode aller Basisklassen aufruft.
Ich habe versucht, dies zu schreiben, aber es wird nicht kompiliert:
class Foo
{
public:
void method()
{
std::cout << "Foo::method()\n";
}
};
class Bar
{
public:
void method()
{
std::cout << "Bar::method()\n";
}
};
template <typename... Ts>
class Combined: public Ts...
{
public:
Combined(const Ts&... ts): Ts(ts)... {}
Combined(Ts&&... ts): Ts(std::move(ts))... {}
template <typename U>
void call_methods()
{
U::method();
}
template <typename U, typename... Us>
void call_methods()
{
U::method();
call_methods<Us...>();
}
void method()
{
call_methods<Ts...>();
}
};
int main(int argc, char *argv[])
{
Combined<Foo, Bar> obj({}, {});
obj.method();
return 0;
}
Der Compiler sagt folgendes:
test.cpp:42:9: error: call to member function 'call_methods' is ambiguous
call_methods<Us...>();
^~~~~~~~~~~~~~~~~~~
test.cpp:47:9: note: in instantiation of function template specialization
'Combined<Foo, Bar>::call_methods<Foo, Bar>' requested here
call_methods<Ts...>();
^
test.cpp:57:9: note: in instantiation of member function
'Combined<Foo, Bar>::method' requested here
obj.method();
^
test.cpp:33:10: note: candidate function [with U = Bar]
void call_methods()
^
test.cpp:39:10: note: candidate function [with U = Bar, Us = <>]
void call_methods()
^
Grundsätzlich besteht eine Mehrdeutigkeit zwischen call_methods<U = Bar>
und call_methods<U = Bar, Us = <>>
. Aber wenn ich a deklariere void call_methods() {}
, wird es call_methods<Us...>();
aus irgendeinem Grund nicht mit dem übereinstimmen .
Wenn es noch nicht klar ist, möchte ich Combined<Foo, Bar>::method()
anrufen Foo::method()
und Bar::method()
.
Ich weiß, dass ich dies wahrscheinlich implementieren kann, indem ich a tuple
mit den Objekten der entsprechenden Typen als Member habe und einfach über sie iteriere, aber ich möchte wirklich eine Lösung finden, die dem, was ich geschrieben habe, näher kommt.
Um Ihre Lösung zu reparieren, deaktivieren Sie die zweite Überladung, wenn das Parameterpaket leer ist:
template <typename U, typename... Us>
typename std::enable_if< (sizeof...(Us) > 0) >::type
call_methods()
{
U::method();
call_methods<Us...>();
}
Beseitigt Mehrdeutigkeiten.
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen