Reputation: 16401
Based on: How do I expand a tuple into variadic template function's arguments?
#include <string>
#include <iostream>
#include <tuple>
template <typename... Args>
void print_all(const Args &... args) {
((std::cout << " " << args), ...) << std::endl;
}
int main()
{
// Create a tuple
auto values = std::make_tuple(1, 2, 3.4f, 4.5, "bob");
// Need to pass the tuple through the lambda for template type deduction and to pass param to template function?
std::apply([](auto &&... args) { print_all(args...); }, values);
// This does not work - other then there is no parameter I can't see how this does not work
// and how the lambda does work as it has the same (roughly) param list
std::apply(print_all(), values);
return 0;
}
can someone explain why one works and the other does not?
Upvotes: 2
Views: 62
Reputation: 123431
Behind the scences, this lambda expression [](auto &&... args) { print_all(args...); }
is roughly of type:
struct [unnamed] {
template <typename ...Args>
void operator()(Args&&...args) { ... };
};
It is a type with a templated operator()
, ie overload resolution and template argument dedcution only take place once the operator()
is actually called. print_all
on the other hand is a template, hence you cannot pass it to std::apply
.
In other words, no matter what Args...
is, the lambda is always of same type, but print_all
isn't. You would need to instantiate it before you can get a pointer to the function. As mentioned by Scheff, this is fine:
std::apply(&print_all<int, int, float, double, const char*>, values);
Upvotes: 4