C++26静态反射提案为语言引入了原生的编译期反射能力,开发者可以在不依赖第三方库的情况下,在编译阶段获取类型、函数、成员变量等程序实体的元信息,大幅简化元编程相关的开发工作。

静态反射提案的核心基础概念
静态反射的核心是std::meta::info类型,它是所有反射元信息的载体,编译期可以通过反射运算符^获取对应实体的反射信息。比如获取一个类型的反射信息可以写成^int,获取变量的反射信息可以写成^var。
反射信息本身可以在编译期处理,通过std::meta命名空间下的相关接口可以提取反射信息的具体内容,比如类型名称、成员列表、函数参数等。
基础使用步骤
1. 获取实体的反射信息
首先需要通过反射运算符获取目标实体的std::meta::info对象,支持反射的实体包括类型、变量、函数、枚举、命名空间等。
#include <meta>
#include <iostream>
// 定义一个测试结构体
struct TestStruct {
int id;
double value;
void print() const {}
};
int main() {
// 获取结构体的反射信息
constexpr std::meta::info struct_info = ^TestStruct;
// 获取结构体成员id的反射信息
constexpr std::meta::info id_info = ^TestStruct::id;
return 0;
}
2. 提取反射信息的具体内容
通过std::meta提供的接口可以提取反射信息的具体属性,比如使用std::meta::name_of获取实体的名称,使用std::meta::members_of获取类型的成员列表。
#include <meta>
#include <iostream>
#include <array>
struct TestStruct {
int id;
double value;
void print() const {}
};
int main() {
constexpr std::meta::info struct_info = ^TestStruct;
// 获取类型名称
constexpr std::string_view struct_name = std::meta::name_of(struct_info);
std::cout << "结构体名称: " << struct_name << std::endl;
// 获取成员列表
constexpr auto members = std::meta::members_of(struct_info);
std::cout << "成员数量: " << members.size() << std::endl;
// 遍历成员并打印名称
for (const auto& member : members) {
std::cout << "成员名称: " << std::meta::name_of(member) << std::endl;
}
return 0;
}
3. 编译期反射信息的使用
静态反射的所有操作都可以在编译期完成,因此反射结果可以用于模板参数、constexpr计算等场景,不会产生运行期开销。
#include <meta>
#include <iostream>
struct Point {
int x;
int y;
};
// 编译期根据反射信息计算成员数量
template<std::meta::info T>
constexpr int get_member_count() {
return std::meta::members_of(T).size();
}
int main() {
constexpr int count = get_member_count<^Point>();
std::cout << "Point成员数量: " << count << std::endl;
return 0;
}
常见应用场景示例
自动生成序列化代码
利用静态反射可以自动遍历类型的所有成员,生成对应的序列化逻辑,避免手动编写重复的序列化代码。
#include <meta>
#include <iostream>
#include <string>
struct User {
int id;
std::string name;
double score;
};
// 简单的序列化函数,自动处理所有成员
template<typename T>
void serialize(const T& obj) {
constexpr auto members = std::meta::members_of(^T);
std::cout << "序列化" << std::meta::name_of(^T) << "对象:" << std::endl;
// 这里仅为示例,实际需要根据成员类型做更细致的处理
[<obj...>] <std::size_t... I>(std::index_sequence<I...>) {
((std::cout << std::meta::name_of(members[I]) << ": " << obj.*(std::meta::pointer_of(members[I])) << std::endl), ...);
}(std::make_index_sequence<members.size()>{});
}
int main() {
User u{1, "张三", 95.5};
serialize(u);
return 0;
}
编译期类型检查
可以在编译期检查类型是否满足特定的约束,比如是否包含某个成员函数、成员变量的类型是否符合要求等。
#include <meta>
#include <type_traits>
struct HasPrint {
void print() const {}
};
struct NoPrint {};
// 检查类型是否包含print成员函数
template<typename T>
constexpr bool has_print_method() {
constexpr auto members = std::meta::members_of(^T);
for (const auto& member : members) {
if (std::meta::is_function(member) && std::meta::name_of(member) == "print") {
return true;
}
}
return false;
}
static_assert(has_print_method<HasPrint>(), "HasPrint应该有print方法");
static_assert(!has_print_method<NoPrint>(), "NoPrint不应该有print方法");
int main() {
return 0;
}
注意事项
- 静态反射提案目前仍在C++26的标准制定流程中,不同编译器的支持程度可能存在差异,使用前需要确认编译器是否已经实现了相关特性。
- 反射运算符
^只能用于编译期可确定的实体,运行期动态生成的实体无法使用静态反射获取信息。 - 提取反射信息时需要注意接口的参数要求,大部分
std::meta接口都要求传入constexpr的std::meta::info对象。
C++26静态反射reflection提案编译期反射修改时间:2026-07-15 12:30:34