可变高阶函数的重载分辨率
Overload resolution with variadic higher order functions
假设我有一个可变高阶函数
template<typename F, typename ...Args>
void execution(F func, Args&&... args)
{
func(std::forward<Args>(args)...);
}
对于这个重载集
void f() {}
void f(int arg) {}
无法解析重载
int main()
{
execution(f, 1);
execution(f);
return 0;
}
然而,如果只提供了两者中的一个,程序将编译
- 为什么会这样?为什么模板参数演绎失败?
如果我从集合中删除
f()
并用f(arg, arg2)
替换它,仍然存在问题。是否有一个解决方案,或我总是必须提供函数的类型作为模板参数?execution<void()>(f);
在进行模板类型推导时,编译器不会分析这些类型在函数内部是如何使用的。因此,在推导模板形参时,编译器看不到不同模板实参之间的关系。因此,额外的可变模板参数根本无关紧要,问题可以简化为
template<typename Func> void execution(Func func);
void f();
void f(int);
execution(f);
有了这段最小化的代码,很明显为什么模板参数推导失败了。
你可以通过让你的第一个参数显式地依赖于剩下的模板参数来解决这个问题,例如:
template<typename... Args>
void execution(void (*func)(Args ...), Args ... args)
{
func(std::forward<Args>(args) ...);
}
您需要一个重载集合对象。这是一个对象,表示f
的整个重载函数集:
struct f_overload_set {
template<typename...As>
auto operator()(As&&...as)->
decltype(f(std::declval<As>()...))
{ return f(std::forward<As>(as)...); }
};
现在将f_overload_set{}
传递给template
函数。
template
的函数值参数必须是值,并且在当前c++中没有第一个类值表示函数的整个重载集。符号f
在每个使用点被消歧为一个重载:但这需要在使用点的直接上下文。以上将推迟消歧,直到我们手边有了参数。
没有特定的函数'f'可用:
简化:template<typename F>
void execution(F func)
{}
void f() {}
void f(int arg) {}
int main()
{
execution(f);
return 0;
}
您有两个函数'f'可用于模板参数推导/替换
相关文章:
- C++ 重载分辨率和恒常性
- 模板和重载分辨率
- 为什么重载分辨率不选择模板函数的 std::vector 重载?
- 使用空大括号初始值设定项的重载分辨率:指针还是引用?
- 如何获取通过重载分辨率选择的函子签名
- 重载分辨率:是否首选直接转换运算符(由于复制省略)?
- 当参数不同时,重载分辨率不会选择模板
- 为什么下面的模板函数重载分辨率不明确
- 重载分辨率:调整 const/ref 是否不比用户定义的转换更好?
- 重载分辨率 C 样式字符串
- 具有引用限定符的模板方法的重载分辨率
- 具有自动功能的模板函数的重载分辨率
- 模板重载分辨率中的位字段
- 重载分辨率如何适用于 std::vector:<int>:insert
- 外部"C"和 "C++" 版本的 qsort()/bsearch() 上的重载分辨率
- 数组衰减为指针和重载分辨率
- 为什么重载分辨率不选择第一个函数?
- 从幻数到int或long的重载分辨率(范围为v3)
- 函数重载分辨率
- 具有多个函数和多个转换运算符的重载分辨率