Reputation: 26973
Typically the idiom to pass a lambda functor to a method relies on templating the argument:
template<typename Functor>
void apply(Functor f)
{
f(stuff);
}
However, the C++ language doesn't support template arguments for virtual declarations. Hereby the problem: There is no succinct way to define a virtual interface that handles some lambda:
virtual void apply(Lambda???) = 0;
Perhaps there is one way: converting lambdas to the heavyweight std::function
and using that
Is there another way to pass a lambda to a virtual method besides that one?
I thought perhaps bypassing the limitation by declaring the functor as a type parameter in the type class:
template<typename SomeArgs, typename Functor>
struct interface
{
virtual void apply(Functor&& f) = 0;
};
but lambdas are not necessarily type-compatible even if they have the same signatures, so this doesn't really but me anything. Perhaps std::function
is the only way?
Upvotes: 2
Views: 739
Reputation: 39993
Yes, you have to do something equivalent to std::function
. The reason is that the virtual function you’re calling might be defined in some other translation unit, and so it can’t possibly adapt to whatever implicit conversions or default arguments your lambda might have. All it can do is call a well-known virtual function itself (via std::function<…>::operator()
) which you have defined to call your lambda.
Upvotes: 1