Seth
Seth

Reputation: 80

Is there any reason to wrap a Lambda in a named function?

I recently stumbled upon this example code and I was confused:

auto named_funct(const MyClass& some_class)
{
    return [some_class](const MyClass2& some_other_class)
    {
        return some_class <= some_other_class; // some expression between capture and input parameter to the Lambda
    };
}

Is there any reason at all to wrap an anonymous function in a named function? It seems like an extra function call stack is being created for no reason.

Upvotes: 5

Views: 151

Answers (3)

Quxflux
Quxflux

Reputation: 3303

To add another possible (slightly modified) use case for this pattern: you could return different implementations of the lambda even with different return types based on templated traits like in following example

#include <iostream>
#include <string>

enum class MyTrait
{
    Default,
    Other
};

struct Foo
{
  std::string Baz() const { return "bar"; };
  int Bazz() const { return 42; };
};

template <MyTrait>
struct LambdaGenerator;

template <>
struct LambdaGenerator<MyTrait::Default>
{
    auto operator()(const Foo& foo) const { return [&]{ return foo.Baz(); }; }
};

template <>
struct LambdaGenerator<MyTrait::Other>
{
    auto operator()(const Foo& foo) const { return [&]{ return foo.Bazz(); }; }
};


int main()
{
    std::cout << LambdaGenerator<MyTrait::Default>()(Foo())() << std::endl;
    std::cout << LambdaGenerator<MyTrait::Other>()(Foo())() << std::endl;

    // prints
    // bar
    // 42
}

I quite often used this when working with C++ AMP to implement different variants of GPU targeted algorithms (which in AMP are lambda objects).

Upvotes: 1

Fady Adal
Fady Adal

Reputation: 345

There can be a reason (if, for example, you want partial functions (the ability to do f(x)(y) rather than f(x, y))), but there isn't here. The outer input argument is shadowed by the argument of the anonymous function.

Upvotes: 1

Stephen Newell
Stephen Newell

Reputation: 7863

named_funct doesn't execute the lambda, it returns it. You could use it like this:

auto it = std::find_if(std::begin(some_vector), std::end(some_vector),
                       named_funct(some_instance));

The odd thing is that named_funct takes a parameter that it doesn't do anything with, unless you have a copy/paste error (another instance is passed to the actual lambda). This example is also so trivial I don't see the benefit of a lambda, but if named_funct's argument was captured and used somehow, this is a useful pattern.

Upvotes: 3

Related Questions