lurscher
lurscher

Reputation: 26973

Passing a lambda to a virtual function

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

Answers (1)

Davis Herring
Davis Herring

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

Related Questions