能否用C++的反射实现default_member_initializer_of?

编程语言 2026-07-09

我注意到随 has_default_member_initializer 一起提供的C++反射功能,但没有与之匹配的 default_member_initializer_of。是否可以使用C++26的反射工具来实现这个?

例如,给定以下内容:

struct test
{
    int value = 42;
};

是否可以实现一个 default_member_initializer_of,使以下情况成功?

static_assert(has_default_member_initializer(^^test::value));
static_assert(default_member_initializer_of(^^test::value) == reflect_constant(42));

尝试使用类似于 constant_of 的方法会失败,而且我也没能找出一个通过构造一个 test 的实例(来自类似于 parent_of 的某些东西,在接收 ^^test::value 时)并从中提取值来“强制”实现的好办法。

我希望可以在把一个 std::meta::info 作为函数的参数传递时实现这一点,但也愿意探索模板的用法。

解决方案

是否可以使用C++26的反射提供的工具来实现这个?

一般来说,不是。默认成员初始化表达式是一个任意表达式,并不一定是常量表达式。

关于你究竟想从 default_member_initializer_of 得到什么答案,仍然是一个待定的问题。也许最有用的是一个表示该表达式的反射——这样你就可以自己评估该表达式(它不必是常量表达式)。但C++26还没有表示表达式的反射。

但在以下特定情形下:(1) 父类型是constexpr-默认构造可构造的,且 (2) 初始化器是常量表达式,那么你可以近似得到结果:

template <class T, std::meta::info R>
inline constexpr auto impl = T().[:R:];

consteval auto default_member_initializer_of(std::meta::info nsdm) -> std::meta::info {
    if (not has_default_member_initializer(nsdm)) {
        throw 42; // something more meaningful presumably
    }
    return constant_of(substitute(^^impl, {parent_of(nsdm), reflect_constant(nsdm)}));
}

struct test {
    int value = 42;
};

static_assert(default_member_initializer_of(^^test::value) == std::meta::reflect_constant(42));

我认为那是你所能做到的最好办法。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章