对 select 成员变量使用元编程
Using meta programming to select member variables
我正在尝试使用 boost 序列化创建一个游戏保存系统,并希望为客户端创建一种简单的方法来 select 成员变量以进行序列化。
基本上我希望用户输入这样的内容:
class apple : public Actor
{
public:
int a;
bool isTasty;
float unimportantData;
SET_SAVED_MEMBERS(a, isTasty);
};
我希望将其扩展为类似
的内容
class apple : public Actor
{
public:
// ...
template<typename Archive>
void serialize(Archive& arch, const unsigned int version)
{
arch & BOOST_SERIALIZATION_NVP(a);
arch & BOOST_SERIALIZATION_NVP(isTasty);
}
当然,如果需要比这多几个宏就好了
我擅长模板元编程(最好)或预处理器元编程。
C++11 也可以。
感谢您的帮助!
以前我有一个我无法测试的以提升为重点的答案。使用模板元编程和宏的组合,这里有一些更容易理解的东西:
#include <iostream>
// Build a base template for the save Implementation
template <typename... ARG_TYPES>
struct save_impl;
// Create a DoSerialize function that will recursively serialize all objects.
template <typename Archive, typename FIRST_TYPE, typename... OTHER_TYPES>
struct save_impl<Archive, FIRST_TYPE, OTHER_TYPES...> {
static void DoSerialize(Archive& arch, FIRST_TYPE & arg1, OTHER_TYPES&... others) {
// Instead of printing in the next line, do: arch & BOOST_SERIALIZATION_NVP(a);
std::cout << arch << arg1 << std::endl;
save_impl<Archive, OTHER_TYPES...>::DoSerialize(arch, others...);
}
};
// Base case to end recursive call of struct-based DoSerialize
template <typename Archive>
struct save_impl<Archive> {
static void DoSerialize(Archive& arch) { ; }
};
// Create a DoSerialize function that will call struct-based implementation.
template <typename Archive, typename... ARG_TYPES>
void DoSerialize(Archive & arch, ARG_TYPES&... args) {
save_impl<Archive, ARG_TYPES...>::DoSerialize(arch, args...);
}
// Create the desired macro to add the serialize function to a class.
#define SET_SAVED_MEMBERS(...) \
template<typename Archive> \
void serialize(Archive& arch) { \
DoSerialize(arch, __VA_ARGS__); \
}
目前我正在打印它以便测试它(但在您需要更改的行上方注明)。这是使用您的苹果示例的测试:
class apple {
public:
int a;
bool isTasty;
float unimportantData;
SET_SAVED_MEMBERS(a, isTasty);
};
int main() {
apple a = {7, false, 2.34};
a.isTasty=true;
a.serialize("Archive: ");
}
请注意,我发送的是一个字符串而不是一个存档对象——这与它当前正在使用打印的事实相得益彰。
我正在尝试使用 boost 序列化创建一个游戏保存系统,并希望为客户端创建一种简单的方法来 select 成员变量以进行序列化。
基本上我希望用户输入这样的内容:
class apple : public Actor
{
public:
int a;
bool isTasty;
float unimportantData;
SET_SAVED_MEMBERS(a, isTasty);
};
我希望将其扩展为类似
的内容class apple : public Actor
{
public:
// ...
template<typename Archive>
void serialize(Archive& arch, const unsigned int version)
{
arch & BOOST_SERIALIZATION_NVP(a);
arch & BOOST_SERIALIZATION_NVP(isTasty);
}
当然,如果需要比这多几个宏就好了
我擅长模板元编程(最好)或预处理器元编程。
C++11 也可以。
感谢您的帮助!
以前我有一个我无法测试的以提升为重点的答案。使用模板元编程和宏的组合,这里有一些更容易理解的东西:
#include <iostream>
// Build a base template for the save Implementation
template <typename... ARG_TYPES>
struct save_impl;
// Create a DoSerialize function that will recursively serialize all objects.
template <typename Archive, typename FIRST_TYPE, typename... OTHER_TYPES>
struct save_impl<Archive, FIRST_TYPE, OTHER_TYPES...> {
static void DoSerialize(Archive& arch, FIRST_TYPE & arg1, OTHER_TYPES&... others) {
// Instead of printing in the next line, do: arch & BOOST_SERIALIZATION_NVP(a);
std::cout << arch << arg1 << std::endl;
save_impl<Archive, OTHER_TYPES...>::DoSerialize(arch, others...);
}
};
// Base case to end recursive call of struct-based DoSerialize
template <typename Archive>
struct save_impl<Archive> {
static void DoSerialize(Archive& arch) { ; }
};
// Create a DoSerialize function that will call struct-based implementation.
template <typename Archive, typename... ARG_TYPES>
void DoSerialize(Archive & arch, ARG_TYPES&... args) {
save_impl<Archive, ARG_TYPES...>::DoSerialize(arch, args...);
}
// Create the desired macro to add the serialize function to a class.
#define SET_SAVED_MEMBERS(...) \
template<typename Archive> \
void serialize(Archive& arch) { \
DoSerialize(arch, __VA_ARGS__); \
}
目前我正在打印它以便测试它(但在您需要更改的行上方注明)。这是使用您的苹果示例的测试:
class apple {
public:
int a;
bool isTasty;
float unimportantData;
SET_SAVED_MEMBERS(a, isTasty);
};
int main() {
apple a = {7, false, 2.34};
a.isTasty=true;
a.serialize("Archive: ");
}
请注意,我发送的是一个字符串而不是一个存档对象——这与它当前正在使用打印的事实相得益彰。