用于名称空间限定的C ++预处理程序标记粘贴

时间:2015-08-27 14:50:07

标签: c++ c++11 c-preprocessor

我在gcc 4.7.1(std = c ++ 11)中遇到了预处理程序令牌粘贴运算符的问题。即,请考虑以下代码:

// Create a name for a global map (this works)
#define GLOBAL_MAP(name) g_map_ ## name // This works fine

// Now, namespace qualify this map (this fails to compile when used)
#define NS_QUAL_GLOBAL_MAP(name) SomeNamespace:: ## GLOBAL_MAP(name)

使用场景 - 首先是地图定义:

std::map<std::string,std::string> GLOBAL_MAP(my_map);

namespace SomeNamespace
{

std::map<std::string,std::string> GLOBAL_MAP(my_map);

}

现在用法:

void foo()
{
    bar(GLOBAL_MAP(my_map)); // This compiles fine
    baz(NS_QUAL_GLOBAL_MAP(my_map)); // This fails to compile with:
                                     // error: pasting "::" and "NAME_MAP" does not give a
                                     // valid preprocessing token
}

我认为可能发生的事情是它在GLOBAL_MAP之后将##解释为粘贴的标记,而不是要进一步扩展的宏。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:12)

令牌粘贴生成单个令牌供编译器读取。这不是您想要的 - ::本身就是一个有效的C ++令牌,但::g_map_my_map不是编译器知道的令牌。

因此,删除令牌粘贴操作符:

#define NS_QUAL_GLOBAL_MAP(type) SomeNamespace::GLOBAL_MAP(type)

答案 1 :(得分:2)

##之后您不需要::运营商。 ##运算符用于形成单个标记,但无论如何SomeNamespace::g_map_mymap都是多个标记。只是做

#define NS_QUAL_GLOBAL_MAP(type) SomeNamespace::GLOBAL_MAP(type)

答案 2 :(得分:0)

您只需要SomeNamespace:: GLOBAL_MAP(name)

您无法将g_map_my_map之类的名称加入::令牌,因为::g_map_my_map不是有效令牌,而是两个令牌。所以只要把它们放在一起,不要试图加入它们。

相关问题