为什么字符串concat宏不适用于此“+”案件? [英] Why string concat macro doesn't work for this "+" case?
问题描述
短问题:
是否允许连接特殊符号,例如 +
, -
为字符串连接宏 ##
?例如,
#define OP(var)operator ## var
将 OP(+)
扩展为 operator +
?
确切问题:
#includez3 ++。h
#include< unordered_map>
命名空间z3 {
z3 :: expr operator +(z3 :: expr const& z3 :: expr const&);
}
typedef z3 :: expr(* MyOperatorTy)(z3 :: expr const& z3 :: expr const&
#define STR(var)#var
#define z3Op(var)static_cast< MyOperatorTy>(& z3 :: operator ## var)
#define StrOpPair )\
{STR(var),z3Op(var)}
void test(){
std :: unordered_map< std :: string,MyOperatorTy> strOpMap1 {
{+,static_cast< MyOperatorTy>(& z3 :: operator +)}}; // fine
std :: unordered_map< std :: string,MyOperatorTy> strOpMap2 {StrOpPair(+)}; // error
}
strOpMap2
,使用 clang ++ -c -std = c ++ 11
,它报告:
code>错误:pasting formed'operator +',无效的预处理令牌
< c $ c> g ++ -c -std = c ++ 11 ,它提供:
错误:粘贴运算符和+不给出有效的预处理令牌
=http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html =nofollow>手册由gcc 我发现应该可以concat,但为什么两个编译器发出错误?
您可以粘贴标点符号形成其他标点符号,例如
#define PASTE(a,b)a ## b
int main()
{
int i = 0;
i PASTE(+,+);
// i == 1现在
}
##
运算符用于从其他预处理令牌生成有效的预处理令牌。粘贴的结果必须是有效的预处理令牌。所以这是无效的:
PASTE(i,++)
pre>
因为
i ++
不是预处理令牌;它是两个相邻的标记i
和++
。
可能的令牌列表为(N3797):
- header-name
- 标识符
- pp-number
- 字符文字
- 用户定义字符文字
- 字符串文字
- 用户定义的字符串文字
- 预处理操作或预处理
- 每个非空白字符不能是上述之一
注意:在预处理阶段,关键字不存在;但在预处理之后,应该是关键字的任何标识符被(语义地)转换成关键字。
在您的代码中, operator +
是两个标记: operator
和 +
。所以你不使用 ##
来构建它;
#define OP(punc)operator punc
Short question:
Is it permitted to concat special signs such as +
, -
for the string concatenation macro ##
? For example,
#define OP(var) operator##var
will OP(+)
be expanded to operator+
?
Exact problem:
#include "z3++.h"
#include <unordered_map>
namespace z3 {
z3::expr operator+(z3::expr const &, z3::expr const &);
}
typedef z3::expr (*MyOperatorTy)(z3::expr const &, z3::expr const &);
#define STR(var) #var
#define z3Op(var) static_cast<MyOperatorTy>(&z3::operator##var)
#define StrOpPair(var) \
{ STR(var), z3Op(var) }
void test() {
std::unordered_map<std::string, MyOperatorTy> strOpMap1{
{"+", static_cast<MyOperatorTy>(&z3::operator+)}}; // fine
std::unordered_map<std::string, MyOperatorTy> strOpMap2{StrOpPair(+)}; // error
}
For strOpMap2
, using clang++ -c -std=c++11
, it reports:
error: pasting formed 'operator+', an invalid preprocessing token
while using g++ -c -std=c++11
, it gives:
error: pasting "operator" and "+" does not give a valid preprocessing token
By reading the manual by gcc I find it should be possible to concat, but why both compilers emit errors?
You can paste punctuation to form other punctuation, e.g.
#define PASTE(a,b) a##b
int main()
{
int i = 0;
i PASTE(+,+);
// i == 1 now
}
The ##
operator is for producing a valid preprocessing token from other preprocessing tokens. The result of pasting must be a valid preprocessing token. So this is not valid:
PASTE(i,++)
because i++
is not a preprocessing token; it's two adjacent tokens i
and ++
.
The list of possible tokens is (N3797):
- header-name
- identifier
- pp-number
- character-literal
- user-defined-character-literal
- string-literal
- user-defined-string-literal
- preprocessing-op-or-punc
- each non-white-space character that cannot be one of the above
Note: at the preprocessing stage, keyword does not exist; but after preprocessing, any identifiers which should be keyword are converted (semantically) into keywords. So you can build keywords by pasting shorter words.
In your code, operator+
is two tokens: operator
and +
. So you do not build it with ##
; you just do one then the other.
#define OP(punc) operator punc
这篇关于为什么字符串concat宏不适用于此“+”案件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!