I am trying to instantiate a templatized class based on an X-macro. However, this is giving me syntax errors error: wrong number of template arguments (0, should be 1)
. What is the correct way to instantiate a templatized class from an x-macro?
#include <string.h>
#include <iostream>
#define FOO \
X(, aaa) \
X(int, bbb) \
template <class T> class A
{
public:
A(){ std::cout << "Hello From A\n";}
};
class B
{
public:
B() {std::cout << "Hello From B\n";}
};
int main()
{
#define X(a,b) \
if (0 == strlen(#a)) { \
printf("%s is empty\n", #b); \
B b; \
} else { \
printf("%s is NOT empty\n", #b); \
A<a> b; \
}
FOO
#undef X
return 0;
}
CodePudding user response:
The issue here isn't that your syntax is wrong, but rather that both branches of the if
and else
get compiled regardless of whether a
is empty or not. The compiler error will trigger because the else
branch will try instantiating A<>
, which isn't legal.
To fix this, you could consider adding a level of indirection. Here's a modified piece of code where the type AHelper
serves to output something of the proper type.
/* By default, use A. */
template <typename... Args> struct AHelper {
using result = A<Args...>;
};
/* But not if there are no arguments. */
template <> struct AHelper<> {
using result = B;
};
int main() {
#define X(a,b) \
AHelper<a>::result b;
FOO
#undef X
}
(Initially, I thought this would be as easy as using if constexpr
rather than if
, but in a non-template context the compiler is supposed to evaluate both the if
and else
branch and the same compiler error results.)