使用C++预处理器元编程:如何获得唯一的值?

我正在利用 C++ 全局变量的构造函数行为以一种简单的方式在启动时运行代码。这是一个非常简单的概念,但有点难以解释,所以让我直接粘贴代码:

struct _LuaVariableRegistration
{
    template<class T>
    _LuaVariableRegistration(const char* lua_name, const T& c_name) {
        /* ... 这个代码将在启动时运行;它会在一个 std::map 中临时保存 lua_name 和 c_name,并在加载 Lua 时将所有临时全局变量注册到 Lua。*/
    }
};

然而,在每次注册 Lua 全局变量时手动实例化这个超级丑陋的类是麻烦的;这就是为什么我创建了以下宏:

#define LUA_GLOBAL(lua_name, c_name) static Snow::_LuaVariableRegistration _____LuaGlobal ## c_name (lua_name, c_name);

所以你所要做的就是把它放在 cpp 文件的全局范围内,一切都能完美地工作:

LUA_GLOBAL("LuaIsCool", true);

现在在 Lua 中,LuaIsCool 将成为一个初始化为 true 的变量!

但是,这里有一个问题:

LUA_GLOBAL("ACCESS_NONE", Access::None);

它变成了:

static Snow::_LuaVariableRegistration _____LuaGlobalAccess::None ("ACCESS_NONE", &Access::None);

:(( 我需要在宏中连接 c_name,否则它将抱怨有两个名称相同的变量;我尝试用 __LINE__ 替换它,但实际上它变成了 _____LuaGlobalAccess__LINE__(即它没有被替换)。

因此,有没有一种方法来获取唯一的字符串,或者其他解决方法?

PS:是的,我知道以 _ 开头的名称是保留的;我仍然会使用它们,目的是像这样选择标准库极不可能使用的名称。此外,它们位于一个命名空间中。

原文链接 https://stackoverflow.com/questions/1781137

点赞
stackoverflow用户9530
stackoverflow用户9530

你需要添加一个额外的宏层来确保预处理器的正确操作:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)

#define LUA_GLOBAL(lua_name, c_name) ... TOKENPASTE2(_luaGlobal, __LINE__) ...

一些编译器也支持__COUNTER__宏,它在每次被评估时扩展为一个新的唯一整数,因此您可以将其用于__LINE__的位置以生成唯一标识符。我不确定它是否是有效的 ISO C,但gcc接受在使用-ansi -pedantic选项时使用它的用法。

2009-11-23 05:10:29