[英]Returning a generic lambda expression from a function causes compiler warnings if an explicit return type is given
我有一个 function 其返回类型是一个简单的通用 lambda 表达式。 (此 function 返回的 lambda 最终作为参数传递给 STL 算法,如std::transform()
或std::accumulate()
)
当 lambda 没有显式返回类型时,编译器不会发出警告:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) {return dst + src; };
}
当 lambda 具有指定的显式返回类型时:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) -> decltype(dst) {return dst + src; };
}
两个编译器都会发出这些类似的警告:
GCC :返回对临时 [-Wreturn-local-addr] 的引用
MSVC :返回局部变量或临时地址
是否应注意此警告,因为它表明该方法存在缺陷(可能的未定义行为?)并且应该重构? 还是它们是“噪音”?
我无法确定为什么显式指定返回类型会导致返回的表达式是“临时的”,而如果不是这样的话。 请解释一下,谢谢!
编辑(添加更多上下文):
使用auto
arguments 到 lambda 的愿望是src
和dst
可能是不同的类型(例如,一个是std::uint8_t
,一个是std::uint_16t
),但我希望返回的总是与dst
参数相同的类型,无论src
的类型如何。
关键是decltype(dst)
是auto const &
(您可以将auto
视为模板类型),因此 lambda 返回一个对常量 object 的引用(我重复:一个引用)。
问题是这是一个参考
dst + src
即:对临时值的引用,即从操作dst + src
创建的临时 object ,当 lambda 结束执行时不再存在。
一个可能的解决方案:删除-> decltype(dst)
或将其更改为-> decltype(dst+src)
,因此您返回一个值,而不是引用。
另一种方法(在这种情况下需要更多的打字,但在更复杂的情况下可能更受欢迎)可以从decltype()
返回的类型中删除引用部分。
所以
-> std::remove_reference_t<decltype(dst)>
或者,正如 Jarod42 所建议的,也
-> std::decay_t<decltype(dst)>
如果dst
的类型支持一元运算符+
(返回相同类型的dst
),另一个简单的解决方案可以是
-> decltype(+dst)
这样, +dst
是一个表达式,而不是一个变量,所以decltype(+dst)
不再是一个引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.