You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将成员类型(嵌套类)作为模板参数生成重复结构类?

问题描述

我有大量如下形式的样板类:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 10:52:10