Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return a reference from lambda

Tags:

c++

c++11

lambda

Extending the solution of this question: Pimpl idiom through macro

I want to be able to return reference values from lambda calls:

#include <iostream>
#include <memory>

class FooImp
{
public:
    int& C() { return _value; }

private:
    int _value{};
};

class Foo
{
public:
    Foo() : 
        _imp{ std::make_unique<FooImp>() }
    {
    }

    int& C()
    {
        // In member function 'int& Foo::C()': cannot bind non-const lvalue reference 
        // of type 'int&' to an rvalue of type 'int'
        return call_impl([&] { return _imp->C(); });
    }

private:
    template<typename fn_t>
    auto call_impl(fn_t fn) -> decltype(fn()) 
    {
        std::cout << "Construct Measure here\n";
        
        struct OnExit{
             ~OnExit() { std::cout << "Construct Log here\n"; }
        } onExit;
        return fn();
    }

    std::unique_ptr<FooImp> _imp;
};

int main()
{
    Foo foo;
    std::cout << foo.C() << "\n";
    return 0;
}

This gives me the error:

error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
   24 |         return call_impl([&] { return _imp->C(); });
      |                ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~

because I am not able to return the temporarily created value in the reference. Is there any possible solution to use the call_impl method with references as return values?

Godbolt

like image 800
RoQuOTriX Avatar asked Mar 12 '26 14:03

RoQuOTriX


1 Answers

The return type should be decltype(auto):

[&]() -> decltype(auto) {return _imp->C();}

This will copy the return type from the underlying function. Or you can manually write -> int & or -> auto & in this case.

like image 106
HolyBlackCat Avatar answered Mar 15 '26 04:03

HolyBlackCat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!