C++ 变量+;价值宏观扩张
我试过了,没有结果。 我的代码如下所示:C++ 变量+;价值宏观扩张,c++,c,C++,C,我试过了,没有结果。 我的代码如下所示: #include "stdafx.h" #include <iostream> #define R() ( rand() ) #define H(a,b) ( a ## b ) #define S(a) ( # a ) #define CAT() H(S(distinct_name_), R()) int main(int argc, _TCHAR* argv[]) { std::cout << CAT() <
#include "stdafx.h"
#include <iostream>
#define R() ( rand() )
#define H(a,b) ( a ## b )
#define S(a) ( # a )
#define CAT() H(S(distinct_name_), R())
int main(int argc, _TCHAR* argv[])
{
std::cout << CAT() << std::endl;
std::cout << CAT() << std::endl;
std::cout << CAT() << std::endl;
return 0;
}
distinct_name_12233
distinct_name_147
distinct_name_435
as a result of concatenating
distinct_name_ (##) rand()
现在我得到一个错误:
项不计算为带1个参数的函数。
这是可以实现的吗
编辑:
几个小时后我终于成功了。预处理器仍然会做一些我无法完全理解的奇怪事情。下面是:
#include "stdafx.h"
#include <iostream>
class profiler
{
public:
void show()
{
std::cout << "distinct_instance" << std::endl;
}
};
#define XX __LINE__
#define H(a,b) ( a ## b )
#define CAT(r) H(distinct_name_, r)
#define GET_DISTINCT() CAT(XX)
#define PROFILE() \
profiler GET_DISTINCT() ;\
GET_DISTINCT().show() ; \
int main(int argc, _TCHAR* argv[])
{
PROFILE()
PROFILE()
return 0;
}
感谢@Kinopiko提供的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu行提示: 不,你不能那样做。宏是编译时的东西,函数只能在运行时调用,因此无法将随机数从rand()
放入宏扩展中。不,您不能这样做。宏是编译时的东西,函数只在运行时调用,因此无法从宏扩展中获得随机数。实际得到的是
std::cout << distinct_name_rand() << std::endl;
你实际上得到的是
std::cout << distinct_name_rand() << std::endl;
std::cout必须将运行时计算值传递给宏,因为宏是在编译时计算的。
尝试:
定义H(a,b)(a#b)
#定义S(a)(#a)
#定义类别(r)H(S(不同名称),r)
std::cout必须将运行时计算值传递给宏,因为宏是在编译时计算的。
尝试:
定义H(a,b)(a#b)
#定义S(a)(#a)
#定义类别(r)H(S(不同名称),r)
std::cout我看到很多人已经正确地回答了这个问题,但作为另一种建议,如果预处理器实现了\uuuuuuuuuuuu时间
或\uuuuuuuuu行
,您可以得到与您想要的结果非常相似的结果,行号或时间连接在一起,而不是一个随机数。我看到很多人已经正确地回答了这个问题,但是作为一个替代建议,如果您的预处理器实现了\uuuuuuuuuuuuuuu
或\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,而不是一个随机数。如果需要调试,您可以始终使用cpp filename.cpp
查看C预处理器的输出。此外,S(distinct\u name)
将为您提供(“distinct\u name”)
,使用R()
进行连接,即使rand()会产生随机数(“distinct_name”(1233)
。您不需要#a
步骤和括号。#
运算符使用原始标记,而不是字符串。我甚至不确定在尝试连接)
和时是否会收到错误消息(
,两者都是标点符号。也就是说,它们分割标记,但是##
会尝试将它们连接成一个标记,这只会导致错误。它不应该产生任何不同的输出,但我更喜欢cc-e
,以防特定编译器有自己的特殊设置或宏。您可以随时查看t的输出如果您需要调试,可以使用cpp filename.cpp
对C预处理器进行调试。此外,S(distinct\u name)
将为您提供(“distinct\u name”)
,使用R()
进行连接,即使rand()会产生随机数(“distinct\u name”)(1233)
。您不需要#a
步骤和括号。#
运算符使用原始标记,而不是字符串。我甚至不确定在尝试连接)
和时是否会收到错误消息(
,两者都是标点符号。也就是说,它们分割标记,但是##
会尝试将它们连接成一个标记,这只会导致错误。它不会产生任何不同的输出,但我更喜欢cc-e
,以防特定编译器有自己的特殊设置或宏。
#define H(a,b) ( a ## b )
#define S(a) ( # a )
#define CAT(r) H(S(distinct_name_), r)
std::cout << CAT(rand()) << std::endl;