从 lambda 返回一个引用

RoQ*_*riX 2 c++ lambda c++11

通过宏扩展本题的解决方案:Pimpl idiom through Macro

我希望能够从 lambda 调用返回参考值:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这给了我错误:

#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;
}
Run Code Online (Sandbox Code Playgroud)

因为我无法返回引用中临时创建的值。是否有任何可能的解决方案来使用call_impl以引用作为返回值的方法?

神箭

Hol*_*Cat 8

返回类型应该是decltype(auto)

[&]() -> decltype(auto) {return _imp->C();}
Run Code Online (Sandbox Code Playgroud)

这将从底层函数复制返回类型。或者在这种情况下您可以手动编写-> int &-> auto &