I have class structure as following. How can I call functions from MultiBase class for all Base classes. Is there any way to iterate over the arguments in parametr pack ?
template <typename T, typename... Args>
class Base : public Base<T>{
};
template <typename T>
class Base<T> {
protected:
void test()
{
std::cout << typeid(m_data).name() << std::endl;
}
void insert(T data)
{
m_data = data;
}
private:
T m_data;
};
template<typename T, typename ...Args>
class MultiBase : public Base<T, Args...>
{
public:
template<typename V>
void insert(ClientId key, V data)
{
Base<V>::insert(key, data);
}
void f()
{
// call test() from Base class for all types from parameter pack
}
};
int main()
{
MultiBase<int,float> ms;
ms.f() // equivalent to calling Base<int>::test() and Base<std::string>::test()
return 0;
}
Thanks in advance for help.
Your code has many issues, for example MultiBase
class only has a single base. But to answer the immediate question: you can use pack expansion. I've provided two examples: expansion in a brace-enclosed initializer list and expansion in a template argument list, and a bonus one for c++17.
#include <iostream>
#include <type_traits>
template <typename Value>
class Base {
protected:
void test() {
std::cout << typeid(Value).name() << std::endl;
}
};
template <typename... Values>
class MultiBase : public Base<Values>... {
public:
void f() {
// hacky solution:
int unused[]{(Base<Values>::test(), 0)...};
// generic recursive solution:
f_impl<Values...>();
// c++17 simplifies this with fold-expressions:
// (Base<Values>::test(), ...);
}
private:
template <typename First, typename... Others>
void f_impl() {
Base<First>::test();
f_impl<Others...>();
}
// overload to terminate recursion,
// SFINAE to only be eligible for empty parameter pack
template <typename... Others, typename = std::enable_if_t<sizeof...(Others) == 0>>
void f_impl() {
}
};
int main() {
MultiBase<int, float, const char*> ms;
ms.f();
return 0;
}