如何实现适配不同枚举类型模板参数的通用C++模板函数?
解决方法
核心问题有两个:一是依赖类型的成员模板调用需要显式加template关键字,二是要让通用函数适配不同枚举类型作为非类型模板参数。
1. 基础实现(兼容C++11及以上)
先明确枚举和类的定义:
// 定义不同枚举类型 enum class my_enum { VAL1, VAL2 }; enum class other_enum { OPT1, OPT2 }; // 类A:foo的模板参数为my_enum类型 class A { public: template<my_enum E> void foo(int x) { // 示例逻辑 if (E == my_enum::VAL1) {} } }; // 类B:foo的模板参数为other_enum类型 class B { public: template<other_enum E> void foo(int x) { // 示例逻辑 if (E == other_enum::OPT1) {} } };
编写通用do_it函数时,需要指定枚举类型和对应枚举值,同时在调用成员模板时添加template关键字(因为item的类型依赖于模板参数T,编译器无法自动识别foo是模板):
template<typename T, typename EnumType, EnumType E> void do_it(T* item, int x) { // 必须加template关键字,告知编译器foo是成员模板 item->template foo<E>(x); }
调用示例:
A a; do_it<A, my_enum, my_enum::VAL1>(&a, 10); B b; do_it<B, other_enum, other_enum::OPT1>(&b, 20);
2. 简化实现(C++17及以上)
利用C++17的auto非类型模板参数,可以省略显式指定枚举类型,让编译器自动推导:
template<typename T, auto E> void do_it(T* item, int x) { item->template foo<E>(x); }
调用时更简洁:
A a; do_it<A, my_enum::VAL1>(&a, 10); B b; do_it<B, other_enum::OPT1>(&b, 20);
关键注意点
- 调用依赖于模板参数的成员模板函数时,必须在
foo前加template关键字,否则编译器会把<解析为小于运算符,导致编译错误。 - 若需兼容C11/14,必须显式指定枚举类型;C17及以上可用
auto非类型模板参数简化代码。
内容的提问来源于stack exchange,提问作者Lajos Nagy
相关产品推荐
相关产品推荐

