可变参数宏中的模板推导失败

template deduction failure in variadic macro

我的宏中的 decltype(__VA_ARGS__) 仅针对单个参数编译,而不是在传递多个参数时编译。

我想要实现的是根据运行时条件调用可变参数函数。 我的打印机的参数计算起来可能很昂贵,因此我不想在我的条件为假时不评估这些参数。

下面是一个最简单的示例。任何对此 question/description 的改写意见也表示赞赏。

#include <iostream>
#include <utility>
#include <functional> 

#define PRINT_IF(printer, cond, ...) if(cond) std::invoke(&Printer::print<decltype(__VA_ARGS__)>, printer, __VA_ARGS__)

// Some Fixed Printer Interface ... 
class Printer{
public:

    void print(){}
    
    template <typename T, typename... Types> 
    void print(T&& var1, Types&&... var2) 
    { 
        std::cout << var1 << std::endl ; 
        print(var2...);
    }
    
};


int main()
{
    Printer p;
    
    PRINT_IF(p, returns_false(), very_expensive_string()); // compiles and expensive operation skipped 
    PRINT_IF(p, true, 1); // compiles
    PRINT_IF(p, true, 1, 2, 3); // doesn't compile
    
    // The macro should also handle pointers.
    PRINT_IF(&p, true, 1, 2, 3);

    return 0;
}

您可以这样做以避免发现模板过载:

template <class T>
auto add_pointer(T&& t) {
    if constexpr (std::is_pointer_v<std::remove_reference_t<T>>) {
        return t;
    }
    else {
        return &t;
    }
}

#define PRINT_IF(printer, cond, ...) if(cond) add_pointer(printer)->print(__VA_ARGS__)

这让 ->print 推导模板参数以避免必须找到重载,如果还没有,只需使用 add_pointerprinter 转换为指针。