【发布时间】:2015-11-22 00:41:27
【问题描述】:
我在使用 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 解释为用于粘贴的标记,而不是要进一步扩展的宏。我该如何解决这个问题?
【问题讨论】:
-
为什么有人会否决一个完全合法的 C++ 预处理器问题/错误?有些人的傲慢让我震惊。
-
我认为它没有显示任何研究成果并且没有用处。错误给出了答案:
pasting "::" and "NAME_MAP" does not give a valid preprocessing token"。阅读错误似乎是面对编译器错误时应该进行的最低限度的研究。 -
@Jonathan,我阅读了错误并理解了错误。我只是不确定为什么会出现错误。当这被接受的答案解释时,很明显我添加了一种预处理器“间接级别”,在某种意义上说,这是没有必要的。对这类问题投反对票除了傲慢之外别无他法。当我们在这里编程和查询它们时,我们都会犯错误,即使它们是暂时的头脑放屁的结果,这也是 StackOverflow 的全部意义所在。
-
而且我不认为暂时的头脑放屁会产生一个对未来有帮助的好问题。你问了这个问题,得到了答案,太好了。但我不认为解决临时的头脑放屁对网站的长期有用。当问题是由一个简单的拼写错误造成的,这是一个有效的关闭原因,我认为一个容易纠正的简单错误几乎属于同一类别。 (更不用说您没有按照“为什么此代码不起作用?”问题的要求发布 MCVE,这是关闭和/或否决投票的另一个原因)。跨度>
-
作为记录,注意到@JonathanWakely 的 cmets,我认为这个问题在 3 年后非常有用。真正的问题是“解决方法是什么?”答案很好地提供了这一点。并非每个问题都需要惊天动地才有用。
标签: c++ c++11 c-preprocessor