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?
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.