Why can std::apply call a lambda but not the equivalent template function?

The following code snippet (compiled using gcc 6.3.0 on OS X with -std=c++17) demonstrates my conundrum:

#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>&)'
}

Why can apply successfully deduce the call to the lambda but not the call to the template function? Is this the expected behavior and, if so, why?


The difference between the two is that p is a function template, while q - a generic lambda - is pretty much a closure class with a templated call operator .

Although the definition of said call operator is very much the same as p definition, the closure class is not a template at all, and therefore it doesn't stay in a way of template argument resolution for std::experimental::apply .

This can be checked by defining p as a functor class:

struct p
{
   auto operator()(auto... args)
   { return (... * args); }
};
链接地址: http://www.djcxy.com/p/95596.html

上一篇: UserWarning:不标签:NUMBER:存在于所有培训示例中

下一篇: 为什么std :: apply可以调用一个lambda,但不能使用等价的模板函数?