用于命名空间限定的C ++预处理器令牌粘贴 [英] C++ preprocessor token pasting for namespace qualification

查看:39
本文介绍了用于命名空间限定的C ++预处理器令牌粘贴的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 //为全局地图创建一个名称(此方法有效)#define GLOBAL_MAP(name)g_map_ ## name//工作正常//现在,名称空间限定了此映射(使用时无法编译)#定义NS_QUAL_GLOBAL_MAP(名称)SomeNamespace :: ## GLOBAL_MAP(名称) 

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

  std :: map< std :: string,std :: string>GLOBAL_MAP(my_map);命名空间SomeNamespace{std :: map< std :: string,std :: string>GLOBAL_MAP(my_map);} 

现在的用法:

  void foo(){bar(GLOBAL_MAP(my_map));//这样编译就可以了baz(NS_QUAL_GLOBAL_MAP(my_map));//无法使用以下命令进行编译://错误:粘贴"::"和"NAME_MAP"不会给出//有效的预处理令牌} 

我认为可能正在发生的是,它会将 ## 之后的 GLOBAL_MAP 解释为粘贴的令牌,而不是要进一步扩展的宏.我该如何解决?

解决方案

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

因此,删除令牌粘贴运算符:

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

I am having trouble with the preprocessor token pasting operator in gcc 4.7.1 (std=c++11). Namely, consider the following code:

// 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)

Usage scenarios - first the map definitions:

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

namespace SomeNamespace
{

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

}

Now the usage:

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
}

What I believe might be happening is that it is interpreting GLOBAL_MAP after ## as a token for pasting rather than a macro to be further expanded. How do I get around this?

解决方案

Token pasting generates a single token for the compiler to read. This isn’t what you want here — :: is a valid C++ token on its own, but ::g_map_my_map isn’t a token that the compiler knows.

Hence, remove the token pasting operator:

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

这篇关于用于命名空间限定的C ++预处理器令牌粘贴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆