Why does std :: apply call a lambda but not an equivalent template function?

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

#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 I successfully apply the output to lambda, but not calling the template function? This is the expected behavior, and if so, why?

+7
c ++ lambda templates c ++ 17
source share
1 answer

The difference between the two is that p is the function template, while q - the common lambda - is largely a closure class with the call operator pattern.

Although the definition of the invocation operator is very similar to the definition of p , the closure class is not a template at all, and therefore it does not remain as a template argument resolution for std::experimental::apply .

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

 struct p { auto operator()(auto... args) { return (... * args); } }; 
+4
source share

All Articles