X宏驱动的C++模板类实例化

X-macro driven C++ template class instantiation

提问人:Paul Grinberg 提问时间:8/27/2022 最后编辑:Paul Grinberg 更新时间:8/27/2022 访问量:91

问:

我正在尝试实例化一个基于 X-macro 的模板化类。但是,这给了我语法错误。从 x 宏实例化模板化类的正确方法是什么?error: wrong number of template arguments (0, should be 1)

#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;
}
C G++ X 宏

评论

0赞 KamilCuk 8/27/2022
你打算什么时候做什么? 代码首先要做什么?只是不要使用 X 宏并将“Hello from A”和其他字符串写入输出。如果要使用预处理器检测宏参数是否为空,或者根据参数数重载宏可以这样做。但是,在不知道目标的情况下,很难判断什么是“正确”的——我会说这一切都不是“正确的”,因为你可以只写你想写的 outut 而不使用宏,并且应该避免整体宏。X(, aaa)A<> b;What is the correct way...?

答:

1赞 templatetypedef 8/27/2022 #1

这里的问题不在于您的语法错误,而在于 and 的两个分支都被编译,无论是否为空。编译器错误将触发,因为分支将尝试实例化,这是不合法的。ifelseaelseA<>

要解决此问题,您可以考虑添加一个间接级别。下面是一段修改过的代码,其中类型用于输出正确类型的内容。AHelper

/* 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

}

(最初,我认为这与使用 而不是 一样简单,但在非模板上下文中,编译器应该同时评估 and 分支和相同的编译器错误结果。if constexprififelse