如何将成员类型(嵌套类)作为模板参数生成重复结构类?
问题描述
我有大量如下形式的样板类:
struct Foo1 { using Self = Foo1; template <typename TYPE> using Refl = TYPE::SubClass1; }; struct Foo2 { using Self = Foo2; template <typename TYPE> using Refl = TYPE::SubClass2; };
(其中SubClassX通常是嵌套类,也可以是类型别名)。想要通过模板生成这类类,期望实现类似Foo<SubClass1>的用法(该写法C++不支持),生成等价于Foo1的类,是否有可行技巧?
可行解决方案
C++无法直接将类的嵌套成员名字作为模板参数传递,但可以通过**元函数(类型提取器)**作为模板参数的方式间接实现需求,具体有两种常用技巧:
方法1:模板模板参数(C++11及以上)
定义一个接受“类型提取模板”的主模板,这个提取模板负责从任意TYPE中取出对应的嵌套类型:
// 主模板:接受一个类型提取器模板作为参数 template <template <typename> class SubClassExtractor> struct Foo { using Self = Foo; template <typename TYPE> using Refl = SubClassExtractor<TYPE>; }; // 为每个SubClass定义对应的提取器 template <typename TYPE> using SubClass1Extractor = typename TYPE::SubClass1; template <typename TYPE> using SubClass2Extractor = typename TYPE::SubClass2;
使用方式:
// 等价于原来的Foo1 using Foo1 = Foo<SubClass1Extractor>; // 等价于原来的Foo2 using Foo2 = Foo<SubClass2Extractor>;
方法2:C++20 auto模板参数 + lambda表达式
如果使用C++20及以上,可以利用auto模板参数和constexpr lambda简化代码,无需单独定义提取器:
template <auto Extractor> struct Foo { using Self = Foo; template <typename TYPE> using Refl = decltype(Extractor.template operator()<TYPE>()); };
使用方式:
// 等价于Foo1 using Foo1 = Foo<[]<typename TYPE>() -> typename TYPE::SubClass1 { return {}; }>; // 等价于Foo2 using Foo2 = Foo<[]<typename TYPE>() -> typename TYPE::SubClass2 { return {}; }>;
这里的constexpr lambda作为模板参数,负责从传入的TYPE中提取对应的嵌套类型。
补充:宏简化定义
如果觉得手动写提取器麻烦,可以用宏来批量生成:
#define DEFINE_FOO(FooName, SubClassName) \ template <typename TYPE> \ using SubClassName##Extractor = typename TYPE::SubClassName; \ using FooName = Foo<SubClassName##Extractor> // 生成Foo1和对应的提取器 DEFINE_FOO(Foo1, SubClass1); // 生成Foo2和对应的提取器 DEFINE_FOO(Foo2, SubClass2);
内容的提问来源于stack exchange,提问作者geza
相关产品推荐
相关产品推荐

