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.