【问题标题】:Repeated Class Instantiation without using Identifier不使用标识符的重复类实例化
【发布时间】:2014-09-25 23:58:17
【问题描述】:

我想在模块范围内重复实例化一个类,而不提供唯一的名称。像这样。

MyClass name##__LINE__(); // doesn't work because __LINE__ won't stringify
MyClass name##__LINE__(); // duplicate identifier error - two name__LINE__ variables

有没有办法做到这一点,要么创建一个唯一的名称,要么使用一些匿名上下文,例如初始化程序或结构?

【问题讨论】:

标签: c++ unique anonymous


【解决方案1】:

this answer

#define CONCATENATE_DETAIL(x, y) x##y
#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y)
#define MAKE_UNIQUE(x) CONCATENATE(x, __LINE__)

MyClass MAKE_UNIQUE(name);
MyClass MAKE_UNIQUE(name);
...

或者只是做一个数组:

MyClass arr[N];

为什么这些宏会起作用
C11 标准,6.10.3.1 Argument substitution

在确定了调用类函数宏的参数之后, 发生参数替换。替换列表中的参数,除非前面有 由### 预处理令牌或后跟## 预处理令牌(见下文),是 在其中包含的所有宏都被替换后由相应的参数替换 扩大。在被替换之前,每个参数的预处理标记是 完全替换宏,就好像它们形成了预处理文件的其余部分;没有其他 预处理令牌可用。

C++ 标准中的相应段落 (16.3.1 Argument substitution) 是 C 标准的精确副本。

【讨论】:

  • 谁能验证这个解决方案是否符合标准?我可以期望它适用于所有符合要求的实现吗?
  • 很棒的答案。谢谢!
  • 发现__LINE__ 对于#include 文件并不是唯一的。我改为__COUNTER__,Visual Studio 和 gcc 都支持。
【解决方案2】:

你需要双重嵌套连接运算符

struct A{};

#define JOIN(X, Y) JOIN_DETAIL(X, Y)
#define JOIN_DETAIL(X, Y) JOIN_DETAIL2(X, Y)
#define JOIN_DETAIL2(X, Y) X##Y

int main() {
    A JOIN(a, __LINE__);
    A JOIN(a, __LINE__);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 1970-01-01
    相关资源
    最近更新 更多