So basically I want to define a class that inherits from an arbitrary amount of classes and have a method in it that calls the overloaded method from all the base classes.
I tried writing this, but it won't compile:
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;
}
The compiler says the following:
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()
^
Basically there is an ambiguity between call_methods<U = Bar>
and call_methods<U = Bar, Us = <>>
. But if I declare a void call_methods() {}
, it won't match the call_methods<Us...>();
for some reason.
If it's not clear yet, I want Combined<Foo, Bar>::method()
to call Foo::method()
and Bar::method()
.
I know that I can probably implement this by having a tuple
with the objects of corresponding types as a member and just iterating over them, but I really want to find a solution that's closer to what I wrote.
Aucun commentaire:
Enregistrer un commentaire