首页 > 解决方案 > 如何从模板函数将可变参数传递给宏?

问题描述

我想实现一个类似于verifyUnreal 4 的函数,如果某个表达式不正确,则打印表达式中使用的标签和一些变量。这是一个案例:

int x = ...;
long y = ...;

Verify( x > y, "check-range", x, y);
Verify( y < INT_MAX, "check-range:y", x, y, INT_MAX);

我想的解决方案是下面的函数Verify,我想将所有参数加入宏中的一个字符串GET_STRING_FROM_PARAMETERS。但是我没有弄清楚如何将可变参数从模板函数传递给宏。

这是代码:

#define GET_STRING_FROM_PARAMETERS(...) \
    do {                                                      \
        if (...) {                                            \
            something to be done                              \
        }                                                     \
    } while (false)

template <typename... Ts>
constexpr void Verify(bool expression, const std::string &tag, Ts &&... rest) noexcept {
    if (!expression) {
        std::cout << tag << " " << GET_STRING_FROM_PARAMETERS(rest...);
    }
}

标签: c++macrosvariadic-templates

解决方案


由于多种原因,您的代码将无法编译。您正在使用包含 while 语句的宏 aa 函数,您将参数包直接传递给它,参数包不能像在循环中那样使用。

您不能将参数包传递给宏,因为预处理发生编译代码之前。宏定义不知道模板。您必须使用技巧来保持正确的语法:

 #define PARAMETER_PACK(x)  x...

 #define SOME_OTHER_MACRO(x)  auto lm = \
                    [&, PARAMETER_PACK(x)] { return foo(PARAMETER_PACK(x)); }

 SOME_OTHER_MACRO(Args);

省略号不能是功能宏的参数列表的一部分。它可以是该列表中表达式的一部分,因此在某些情况下您也可以这样做:

#define SOME_OTHER_MACRO(x) g x;

SOME_OTHER_MACRO((Args ...));

在这两种情况下,这都是一种有限且奇怪的方式,最好不要在此类模板中使用宏定义。如果必须,请使用较小的辅助模板。


推荐阅读