C++ 防止lambda的返回类型扣除
由于lambda返回类型的自动推断,下面的代码不可编译 在没有尾随类型的C++14语法术语中,有什么正确的方法可以防止这种推断 编译错误与test()输入上不兼容的类型(右值)有关,该输入需要非常量引用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
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的情况下,我目前正在代码中使用尾部声明,但是你-可能还有其他一些,更现代的简短清晰声明用于此类情况。。。。