Reputation: 941
I'm learning concepts and templates. I'm trying to make a function template that will call another function template. Currently it works with lambda but not with a normal function.
// This also works with lambda but not the normal function:
//void callFunc(std::regular_invocable<T> auto invocable)
template<typename T>
void callFunc(auto invocable)
{
invocable(T(5));
}
// Doesn't work, whether I use "T" or "auto"
//template<typename T>
void testFuncToPass(const auto& a)
{
std::cout << a << " CALLED\n";
}
//...
auto lambda = [](const auto& a){std::cout << a << " CALLED\n";};
//callFunc<int>(testFuncToPass); // ERROR
callFunc<int>([](const auto& a){std::cout << a << " CALLED\n";});
callFunc<int>(lambda);
It says: "error : no matching function for call to 'callFunc'. candidate template ignored: couldn't infer template argument 'invocable:auto'"
Is what I'm trying to do doable? I also tried to use template template parameter but seems that only works for types, not for functions.
Upvotes: 2
Views: 62
Reputation:
You are under the impression that
auto lambda = [](const auto& a){std::cout << a << " CALLED\n";};
is equivalent to
template<typename T>
void lambda(const T& a) { std::cout << a << " CALLED\n"; }
But it's not. It's actually equivalent to:
struct SomeType {
template<typename T>
void operator()(const T& a) const { std::cout << a << " CALLED\n"; }
};
SomeType lambda;
Fun fact: If your lambda captures values and/or references, they become private members of that struct, and marking the lambda as mutable simply removes the const
. Lambdas are effectively just syntactic sugar on top of functors.
Is what I'm trying to do doable?
Unfortunately not as of the current standard. It is possible to accept a templated type as an argument (via some funky-looking syntax), but function templates are still off the table at the moment.
You pretty much have to declare a struct or a class with a templated operator()
like in my example, or wrap them in a lambda:
callFunc<int>([](auto const& a){testFuncToPass(a);});
Upvotes: 3