为什么字符串concat宏不适用于此“+”案件? [英] Why string concat macro doesn't work for this "+" case?

查看:813
本文介绍了为什么字符串concat宏不适用于此“+”案件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

短问题:



是否允许连接特殊符号,例如 + - 为字符串连接宏 ## ?例如,

  #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屋!

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