C++14中如何从可变参数模板类调用所有基类成员函数
如何在MultiBase中调用所有Base类的成员函数并遍历参数包
首先修正你代码中Base类的递归继承错误,当前写法会导致无限递归且无法正确继承所有参数包对应的Base特化,修正后的完整代码及解决方案如下:
#include <iostream> #include <typeinfo> // 前向声明递归版本 template <typename... Args> class Base; // 特化:单个类型的Base 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; }; // 递归版本:继承剩余参数的Base,形成正确的基类链 template <typename T, typename... Args> class Base<T, Args...> : public Base<Args...> { // 自动继承Base<Args...>的所有成员 }; template<typename... Args> class MultiBase : public Base<Args...> { public: // 修正insert函数:原ClientId未定义,此处简化处理 template<typename V> void insert(V data) { Base<V>::insert(data); } // C++17及以上推荐:折叠表达式遍历参数包 void f() { // 展开参数包,逐个调用对应Base类型的test() (Base<Args>::test(), ...); } // 兼容C++11/C++14的方案:递归模板辅助函数 template <typename First, typename... Rest> void call_test_helper() { Base<First>::test(); call_test_helper<Rest...>(); } // 递归终止条件 void call_test_helper() {} // C++11/C++14版本的f() void f_cpp11() { call_test_helper<Args...>(); } }; int main() { MultiBase<int, float> ms; ms.f(); // 依次调用Base<int>::test() 和 Base<float>::test() // ms.f_cpp11(); // 若使用C++11/C++14则调用此版本 return 0; }
关键说明:
修正Base继承结构
递归版本的Base<T, Args...>必须继承Base<Args...>,这样Base<int, float>会继承Base<float>,最终形成包含所有参数类型的基类链,确保MultiBase能访问每个Base特化的成员。遍历参数包的两种方式
- C++17折叠表达式:
(Base<Args>::test(), ...)是最简洁的实现,逗号运算符会依次触发每个参数类型对应的test()调用。 - C11/C14递归模板:通过递归的辅助函数逐个处理参数包中的类型,空参数包时触发终止函数,完成遍历。
- C++17折叠表达式:
protected成员访问
由于MultiBase继承了所有Base特化类,因此可以直接通过Base<Args>::test()调用protected成员,无需额外权限配置。
内容的提问来源于stack exchange,提问作者arek
相关产品推荐
相关产品推荐

