使用__LINE__创建宏以用于不同的变量名

15

可能是重复问题:
使用##和LINE(定位宏中的令牌连接)创建C宏

我尝试使用__LINE__ 宏来生成不同的变量名。我有一个名为Benchmark(位于utils命名空间中)的作用域基准测试类,它的构造函数接受一个字符串。下面是我创建的宏定义:

#define BENCHMARK_SCOPE utils::Benchmark bm##__LINE__(std::string(__FUNCTION__))

不幸的是,这会导致以下错误:

<some_file_name>(59): error C2374: 'bm__LINE__' : 重新定义;多次初始化

这让我得出结论,__LINE__ 宏未被扩展。根据此帖子,我已创建了自己的宏。你有想法为什么 __LINE__ 没有被扩展吗?

编辑:可能编译器信息也很重要。我正在使用 Visual Studio 2010。


嗯。你试过用带空格的 bm## __LINE__ 吗? - Cameron
@Cameron,谢谢你的评论,但是什么也没改变。 - Ivaylo Strandjev
好的,再试一次hack:#define _BENCHMARK_SCOPE(line) utils::Benchmark bm##line(...#define BENCHMARK_SCOPE _BENCHMARK_SCOPE(__LINE__) - Cameron
@Cameron - 仍然无法工作。这里是在 ideone 上的示例:http://ideone.com/5r5l1(尽可能简单) - Ivaylo Strandjev
3个回答

19

你需要使用两个宏的组合:

#define COMBINE1(X,Y) X##Y  // helper macro
#define COMBINE(X,Y) COMBINE1(X,Y)

然后将其用作:

COMBINE(x,__LINE__);

你知道为什么我需要使用两个宏吗? - Ivaylo Strandjev
3
@izomorphius,实际上你的问题是另一个已经解释得很好的问题的重复。我已经在你的问题下进行了评论,请查看。 - iammilind

6
您正在使用标记粘贴。这是在递归宏扩展之发生的(以便您可以通过标记粘贴来获取要调用的宏的名称)。因此:
#define PASTE(a,b) a ## b

将传递给PASTE的确切参数粘贴,然后尝试扩展生成的新令牌。为了获得所需的效果,您需要额外的间接层:

#define PASTE_HELPER(a,b) a ## b
#define PASTE(a,b) PASTE_HELPER(a,b)

在这里,PASTE的参数将在调用PASTE_HELPER之前被展开。

5

试试这段代码,我在以前的项目中使用过

#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#ifdef _MSC_VER // Necessary for edit & continue in MS Visual C++.
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif 


int ANONYMOUS_VARIABLE(var)

编辑:

我认为只有在使用预编译头文件的情况下,您才应该在Visual Studio中使用COUNTER


它也可以使用__LINE__运行。 - Ivaylo Strandjev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接