如何通过元编程从C++函数原型自动生成对应结构体?
问题:从C++函数原型自动生成参数结构体
假设有一个C++函数foo,其原型为:
bool foo (int a, double x, const std::vector<std::string>& v);
能否通过元编程自动创建一个结构体类型,使其成员为该函数的输入参数?例如生成等价于以下代码的结构体:
struct { int arg1; double arg2; std::vector<std::string> arg3; };
我推测可通过《Modern C++ Design》中A.Alexandrescu介绍的技术实现,但想了解是否已有库提供此类‘prototype2struct’功能。
补充背景:我获取的外部foo函数原型不固定,核心需求是封装foo调用以在远程计算机执行,这需要:
- 将调用参数序列化到缓冲区
- 将缓冲区发送至远程计算机
- 在远程计算机执行调用
我的思路是从函数原型生成对应类型,再借助序列化库完成操作。
解决方案
完全可以实现从函数原型自动生成参数结构体的需求,既可以通过手动模板元编程实现,也有现成的库直接支持这类功能,结合你的远程调用场景,以下是具体方案:
一、现成库实现
1. Boost.PFR
Boost.PFR(Plain Old Data Reflection)是专门针对无反射支持的POD类型和函数参数的反射库,它可以直接从函数类型提取参数列表,无需显式定义结构体,就能实现类似结构体的参数打包与序列化:
- 对于函数
foo,可以直接将调用时的参数打包成一个元组,这个元组的类型完全对应函数的参数类型序列 - 大多数序列化库(如Boost.Serialization、Protobuf)都支持元组的序列化,因此可以直接用这个元组完成参数的序列化操作
- 如果确实需要显式的结构体类型,Boost.PFR也支持将函数参数列表映射为匿名结构体,或者通过模板生成具名结构体
示例代码思路:
#include <boost/pfr.hpp> #include <tuple> // 提取foo的参数类型组成元组 using FooArgsTuple = decltype(boost::pfr::tuple_from_args(foo)); // 等价于std::tuple<int, double, std::vector<std::string>> // 打包参数 auto args = std::make_tuple(1, 3.14, std::vector<std::string>{"a", "b"}); // 直接序列化这个元组即可
2. 代码生成工具(Clang LibTooling)
如果你的外部函数原型完全不固定(编译前已知但需批量处理),可以用Clang的LibTooling工具解析C++代码的AST(抽象语法树),自动生成对应参数结构体的代码。这种方式适合批量处理大量函数原型,生成的结构体代码可直接引入项目,配合序列化库使用。
二、手动模板元编程实现
正如你推测的,基于《Modern C++ Design》中的类型萃取技术,可以手动实现函数参数的提取与结构体生成:
- 用模板元函数萃取函数的返回值、参数个数、每个参数的类型
- 借助可变参数模板展开参数类型,生成包含对应成员的结构体
- 为生成的结构体添加序列化支持(或直接复用元组的序列化)
这种方式灵活性高但代码量较大,不如现成库成熟,适合需要高度定制的场景。
结合远程调用场景的建议
- 如果是编译期已知函数原型,优先使用Boost.PFR,无需手写大量元代码,直接完成参数打包与序列化
- 如果是编译前需要批量处理大量外部函数原型,用Clang LibTooling生成结构体代码更高效
- 序列化环节选择支持元组或POD类型的库,比如Boost.Serialization或FlatBuffers,配合生成的参数类型完成缓冲区的序列化与反序列化
内容的提问来源于stack exchange,提问作者abcdefg
相关产品推荐
相关产品推荐

