Home > front end >  X-macro driven C template class instantiation
X-macro driven C template class instantiation

Time:08-27

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

  • Related