繁体   English   中英

具有可变高阶函数的过载分辨率

[英]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;
}

然而,如果只提供两者中的任何一个,程序就会编译

  1. 为什么会这样? 为什么模板参数推断失败?
  2. 如果我从集合中删除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'可用于模板参数扣除/替换

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM