C++ 防止lambda的返回类型扣除

C++ 防止lambda的返回类型扣除,c++,c++14,auto,return-type-deduction,C++,C++14,Auto,Return Type Deduction,由于lambda返回类型的自动推断,下面的代码不可编译 在没有尾随类型的C++14语法术语中,有什么正确的方法可以防止这种推断 编译错误与test()输入上不兼容的类型(右值)有关,该输入需要非常量引用 struct B { int i; }; struct A { B &getB() { return b; } private: B b; }; void test(B &b) { b.i++; } int main() { A a

由于lambda返回类型的自动推断,下面的代码不可编译

在没有尾随类型的C++14语法术语中,有什么正确的方法可以防止这种推断

编译错误与test()输入上不兼容的类型(右值)有关,该输入需要非常量引用

struct B {
    int i;
};

struct A {
    B &getB() { return b; }
private:
    B b;
};

void test(B &b)  {
    b.i++;
}

int main() {
    A a;

    test([&a]() { 
        return a.getB();
    });
    return 0;
}

这里有两个问题


首先,您实际上没有调用lambda,因此您没有将返回值传递到
test
,而是传递函数对象,这显然是一种完全不兼容的类型!通过在lambda之后添加
()
来解决此问题,从而将返回值传递给
test()


其次,您是对的,推导的返回类型将是
B
,而不是
B&
,并且临时对象可能不会绑定到
test(B&)
的ref to non-
const
参数

解决此问题的一种方法是使用尾部返回类型强制引用:

    [&a]() -> B& { .... }
return std::ref(a.getB()));
你似乎知道这一点,但不想这么做。为什么?

另一个选项是返回引用包装器,然后通过值返回,但其行为类似于引用:

    [&a]() -> B& { .... }
return std::ref(a.getB()));

另一种选择是更改
test
,以便能够接受一些临时测试。因为您需要它来修改原始对象,所以您可以让
test
获取指针或其他具有引用语义的类型(智能指针、
std::reference\u包装器
,使
B
在复制时具有引用语义,…)


给学究们的提示:我知道
++(b->I)
中的参数并不是绝对必要的。我觉得更清楚。

我建议您按值接收
b
:无效测试(b)@SergeyAleksandrovich注意
测试
修改了原始对象。谢谢。关于第一个问题,你是对的。你看-这不是真正的代码,而是快速的示例-所以是我的疏忽。关于解决方案-老实说,我希望在没有代码更改的情况下,可能是decltype的情况下,我目前正在代码中使用尾部声明,但是你-可能还有其他一些,更现代的简短清晰声明用于此类情况。。。。