C++ 宏/元程序在编译时确定成员数
我正在开发一个具有基于消息/异步代理类架构的应用程序.将有几十种不同的消息类型,每种都由 C++ 类型表示.
I am working on an application with a message based / asynchronous agent-like architecture. There will be a few dozen distinct message types, each represented by C++ types.
class message_a
{
long long identifier;
double some_value;
class something_else;
...//many more data members
}
是否可以编写允许在编译时计算类中数据成员数量的宏/元程序?
Is it possible to write a macro/meta-program that would allow calculating the number of data members within the class at compile time?
//例如:
class message_b
{
long long identifier;
char foobar;
}
bitset<message_b::count_members> thebits;
我不熟悉 C++ 元编程,但是 boost::mpl::vector 可以让我完成这种类型的计算吗?
I am not familiar with C++ meta programming, but could boost::mpl::vector allow me to accomplish this type of calculation?
推荐答案
不,C++ 中无法知道所有成员的名称或实际有多少成员.
No, there is no way in C++ to know the names of all members or how many members are actually there.
您可以将所有类型存储在您的类中的 mpl::vector
中,但随后您将面临如何将它们变成具有适当名称的成员的问题(如果没有一些宏hacky,您将无法实现).
You could store all types in a mpl::vector
along in your classes but then you face the problem of how to turn them into members with appropriate names (which you cannot achieve without some macro hackery).
使用 std::tuple
代替 POD 是一种通常有效的解决方案,但当您实际使用元组(无命名变量)时会产生令人难以置信的混乱代码,除非您在某个时候转换它或有一个将访问器转发到元组成员的包装器.
Using std::tuple
instead of PODs is a solution that generally works but makes for incredible messy code when you actually work with the tuple (no named variables) unless you convert it at some point or have a wrapper that forwards accessors onto the tuple member.
class message {
public:
// ctors
const int& foo() const { return std::get<0>(data); }
// continue boiler plate with const overloads etc
static std::size_t nun_members() { return std::tuple_size<data>::value; }
private:
std::tuple<int, long long, foo> data;
};
Boost.PP 和 MPL 的解决方案:
A solution with Boost.PP and MPL:
#include <boost/mpl/vector.hpp>
#include <boost/mpl/at.hpp>
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
struct Foo {
typedef boost::mpl::vector<int, double, long long> types;
// corresponding type names here
#define SEQ (foo)(bar)(baz)
#define MACRO(r, data, i, elem) boost::mpl::at< types, boost::mpl::int_<i> >::type elem;
BOOST_PP_SEQ_FOR_EACH_I(MACRO, 0, SEQ)
};
int main() {
Foo a;
a.foo;
}
我没有测试它,所以可能会有错误.
I didn't test it so there could be bugs.
相关文章