Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将点作为参数传递给C宏_C++_Macros_C Preprocessor - Fatal编程技术网

C++ 将点作为参数传递给C宏

C++ 将点作为参数传递给C宏,c++,macros,c-preprocessor,C++,Macros,C Preprocessor,我读过关于StackOverflow的不同相关答案,但没有一个能给我这个问题的答案。 我需要将传递给宏的实体(不一定是字符串)串联起来,并在它们之间使用分隔符(在我的例子中是点)。这是我的密码: #定义STR(x)#x #定义XSTR(x)STR(x) #定义浓度(a,b)a##b #定义浓度(a,b)浓度(a,b) #定义CONC3(_1,_2,_3,S)CONC2(CONC2(_1,_2,S),_3,S) #定义CONC2(1,2,S)CONC(1,CONC(S,2)) #定义连接下划线(1

我读过关于StackOverflow的不同相关答案,但没有一个能给我这个问题的答案。 我需要将传递给宏的实体(不一定是字符串)串联起来,并在它们之间使用分隔符(在我的例子中是点)。这是我的密码:

#定义STR(x)#x
#定义XSTR(x)STR(x)
#定义浓度(a,b)a##b
#定义浓度(a,b)浓度(a,b)
#定义CONC3(_1,_2,_3,S)CONC2(CONC2(_1,_2,S),_3,S)
#定义CONC2(1,2,S)CONC(1,CONC(S,2))
#定义连接下划线(1,2,3)XSTR(CONC3(1,2,3,3))
#定义JOIN_DOT(_1,_2,_3)XSTR(CONC3(_1,_2,_3,)//这里我传递DOT
以下是您如何使用它

std::string下划线=连接下划线(一、二、三);
std::string dot=连接点(一、二、三);//这个不能编译
我可以使用另一种技术来实现这一点。比如:

定义附加点(x)“.”STR(x) #定义CONCSTR3(_1,_2,_3)CONCSTR2(_1,_2)附加点(_3) #定义CONCSTR2(_1,_2)STR(_1)追加点(_2) #定义CONCSTR1(_1)STR(_1) #定义连接点(_1,_2,_3)CONCSTR3(_1,_2,_3) std::string dot_str=连接点(一、二、三); 这将与dot一起工作。但问题是如何通过传递分隔符使其通用

这里有一个链接,可用于播放允许连接有效的预处理令牌,形成有效的预处理令牌

在你的情况下,你可以使用

std::string pi = CONCSTR2(3, 141592);
作为
3
3.
3.141592
都是有效的预处理令牌。但是你不能用

std::string dot = JOIN_DOT(one, two, three);
as
.two
(这是您正在执行的第一个串联)不是有效的预处理令牌。当您的最终目标是形成一个字符串时,最好使用并置提供的字符串文字连接。当目标是标识符时,可以使用第一种方法。

运算符的结果必须是有效的预处理器令牌<代码>一有效,
一。
无效。这就是为什么下划线起作用,而dot不起作用

如果目的是创建字符串,则可以使用处理器前字符串文字连接,而不是令牌粘贴运算符:

#define STR(x) #x
#define JOIN_UNDERSCORE(_1, _2, _3) STR(_1) "_" STR(_2) "_" STR(_3)
可概括为:

#define STR(x) #x
#define JOIN_SYMBOL(_1, _2, _3, symbol) STR(_1) STR(symbol) STR(_2) STR(symbol) STR(_3)
...
const char* underscore = JOIN_SYMBOL(one, two, three, _);
const char* dot = JOIN_SYMBOL(one, two, three, .); 
这不能用于创建变量名,但点也不能用于创建变量名

完全跳过连接是可以做到这一点的,但这有什么好处,我不知道:

#define DUMB_THING(_1, _2, _3, thingie) _1 thingie _2 thingie _3

#include <stdio.h>

int main (void)
{
  typedef struct { int idea; } stupid_t;
  typedef struct { stupid_t stupid; } really_t;
  really_t really;
  DUMB_THING(really, stupid, idea, .) = 42; 
  printf("%d", really.stupid.idea);
}
#定义愚蠢的东西(1,2,3,thingie)1 thingie 2 thingie 3
#包括
内部主(空)
{
typedef结构{int idea;}t;
typedef结构{dumby\u t dumby;}真的;
真的吗?;
愚蠢的东西(真的,愚蠢的,想法);
printf(“%d”,真的。愚蠢。想法);
}

std::string
不是一个东西。在C中,
“a”“b”
相当于
“ab”
,因此您可以这样做:谢谢您的评论,但我需要这个宏也能够生成变量名。比如:
intjoin\u下划线(my,awesome,var)=1将产生
int my_awesome_var=1
请注意,使用宏生成变量名是一个糟糕的想法。
a##b
在宏中用于通过连接两个标记来创建单个标记。这可以用作变量名等<代码>“a”“b”
用于连接字符串文本。你似乎不知道你到底需要哪一个。