【问题标题】:Why can std::apply call a lambda but not the equivalent template function?为什么 std::apply 可以调用 lambda 而不是等效的模板函数?
【发布时间】:2017-08-07 03:52:26
【问题描述】:

以下代码 sn-p(在 OS X 上使用 gcc 6.3.0 和 -std=c++17 编译)演示了我的难题:

#include <experimental/tuple>

template <class... Ts>
auto p(Ts... args) {
  return (... * args);
}

int main() {
  auto q = [](auto... args) {
    return (... * args);
  };

  p(1,2,3,4); // == 24
  q(1,2,3,4); // == 24

  auto tup = std::make_tuple(1,2,3,4);
  std::experimental::apply(q, tup); // == 24
  std::experimental::apply(p, tup); // error: no matching function for call to 'apply(<unresolved overloaded function type>, std::tuple<int, int, int, int>&)'
}

为什么apply可以成功推断出对lambda的调用,但不能推断出对模板函数的调用?这是预期的行为吗?如果是,为什么?

【问题讨论】:

  • 这个问题是指将模板函数传递给另一个函数——这个问题是指在通用 lambda(有效)与模板函数(无效)上使用 apply。
  • "那个问题是指将一个模板函数传递给另一个函数" 就像将p(一个函数模板)传递给apply(另一个函数(模板))一样。 .?
  • 这个问题的答案并没有解释为什么函子类确实有效,也没有提到通用 labmda 与函子类是一样的事实,但除此之外,就是这样

标签: c++ templates lambda c++17


【解决方案1】:

两者之间的区别在于p 是一个函数模板,而q - 一个通用的lambda - 几乎是一个带有模板化调用运算符 的闭包类。

虽然上述调用运算符的定义与p 的定义非常相似,但闭包类根本不是模板,因此它不会停留在std::experimental::apply 的模板参数解析方式中。

这可以通过将p 定义为仿函数类来检查:

struct p
{
   auto operator()(auto... args)
   { return (... * args); }
};

【讨论】:

  • 是的,效果很好。感谢您清楚地阐明了通用 lambda 和模板函数之间的区别——这将在未来成为一个有用的工具。
猜你喜欢
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多