0

I want to repeatedly instantiate a class, within module scope, without providing a unique name. Something like this.

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

Is there some way to do this, either creating a unique name or using some anonymous context, such as an initializer or struct?

jww
  • 97,681
  • 90
  • 411
  • 885
BSalita
  • 8,420
  • 10
  • 51
  • 68

2 Answers2

1

See 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);
...

Or just make an array:

MyClass arr[N];

Why these macros work
C11 standard, 6.10.3.1 Argument substitution:

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

Corresponding paragraph in C++ standard (16.3.1 Argument substitution) is exact copy of C standard's.

Community
  • 1
  • 1
Anton Savin
  • 40,838
  • 8
  • 54
  • 90
  • Can anyone verify that this solution is standards conforming? Can I expect that it will work with all conforming implementations? – BSalita Sep 26 '14 at 14:22
  • Discovered that `__LINE__` isn't unique for #include files. I changed to `__COUNTER__` which is supported by Visual Studio and gcc. – BSalita Oct 13 '14 at 12:51
0

You need to double nest the concatenation operator

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__);
}
walrii
  • 3,472
  • 2
  • 28
  • 47