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

标签 c++ variadic-templates template-argument-deduction variadic-macros

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

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

下面是一个最小的示例。也欢迎任何重新表述此问题/描述的评论。

#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 转换为指针如果还没有的话。

关于c++ - 可变参数宏中的模板推导失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66567828/

相关文章:

C++:将 Args && ... _args 传递给嵌套列表的正确方法?

c++ - 可以给 `std`命名空间添加推导指南吗?

c++ - 为什么我们没有义务实现纯虚析构函数?

C++ - 填充派生类数据成员,同时设置基类属性值

c++ - 使用现有类设计实现功能的问题

templates - C++ std::function-like模板语法

C++ 可变参数模板委托(delegate)周期错误

c++ - 可以从指向成员函数模板参数的指针推导出类类型吗

C++11模板解析错误,使用模板别名进行类型推导

c++ - 将 std::time 与随机整数混合