我想将MyNamespace ::附加到宏定义的函数:
#define transFunc(func) \
dimensionedScalar func(const dimensionedScalar& ds) \
{ \
if (!ds.dimensions().dimensionless()) \
{ \
FatalErrorIn(#func "(const dimensionedScalar& ds)") \
<< "ds not dimensionless" \
<< abort(FatalError); \
} \
\
return dimensionedScalar \
( \
#func "(" + ds.name() + ')', \
dimless, \
MyNameSpace::##func(ds.value()) \
);
\
}
但是当我打电话时
transFunc(Foo)
编译器抛出以下错误:
粘贴“::”和“Foo”不会提供有效的预处理令牌
我上面连接令牌的方式有什么问题?
答案 0 :(得分:6)
##
用于将两个令牌组合在一起以制作单个令牌。因此func##1
之类的东西会扩展为单个标记func1
。
在此处使用它时,它会尝试将::
和Foo
组合在一起以制作单个标记::Foo
。正如错误所说,这不是有效的令牌。你不想在这里有一个令牌;你只想将两个令牌分开:
MyNameSpace::func(ds.value())
答案 1 :(得分:1)
##
适用于宏,它并不适用于常规代码。
您可以按照以下方式执行此操作:
#define ADD_NAMESPACE(NS,FUNC) NS##::##FUNC
现在您可以像这样使用它:
ADD_NAMESPACE(std,cout)<<x1<<ADD_NAMESPACE(std,endl);
但你不能这样做:
std ## :: ## cout<<std ## :: ## endl;
你这样做:
std::cout<<std::endl;
修改强>
此示例适用于gcc版本4.8.5 20150623(Red Hat 4.8.5-16)(GCC):
#include <iostream>
#define ADD_NAMESPACE(NS,FUNC) NS##::##FUNC
int main()
{
ADD_NAMESPACE(std,cout)<<"hello world!"<<ADD_NAMESPACE(std,endl);
return 0;
}
答案 2 :(得分:1)
正如其他人所说,##在编译的标记化阶段(或之后)连接两个标记:
a##b => (a) ## (b) => (ab)
( possibly invalid, like (::bar) instead of (::), (bar) )
注意,这不会通过令牌化程序发回连接的令牌标识符,编译阶段已经完成。可能搞砸的是,这些现在是令牌,而不是原始字符串了
当我(来到派对上)来这里寻找相同的信息时,如果事情仍然没有意义,这里是一个foo.cpp示例:
#define FOO(a) Something::a
int main()
{
FOO( bar );
FOO( cat );
return 0;
}
gcc -E foo.cpp 生成
# 1 "foo.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "foo.cpp"
int main()
{
Something::bar;
Something::cat;
return 0;
}
答案 3 :(得分:0)
给你的函数添加一个前缀怎么样,比如'_':
dimensionedScalar _##func(const dimensionedScalar& ds)
然后你可以将 '_' 与 func 连接起来:
MyNameSpace::_##func(ds.value())