问题描述
我的宏中的 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,1,2,3); // doesn't compile
// The macro should also handle pointers.
PRINT_IF(&p,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_pointer
将 printer
转换为指针(如果还没有)。