14

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?

4
  • Possible duplicate of Pass a function template to other function? Commented Mar 16, 2017 at 5:52
  • That question refers to passing a template function to another function -- this question refers to using apply on a generic lambda (which works) versus a template function (which doesn't). Commented Mar 16, 2017 at 6:06
  • "That question refers to passing a template function to another function" Like passing p (a function template) to apply (another function (template))..? Commented Mar 16, 2017 at 6:08
  • well the answer to that question does not explain why exactly functor class works, and it doesn't mention the fact that generic labmda is the same thing as the functor class, but otherwise yeah, that's it Commented Mar 16, 2017 at 6:10

1 Answer 1

8

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); }
};
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that works perfectly. Thank you for clearly elucidating the difference between a generic lambda and template function -- that will be a helpful tool in the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.