如果给出显式 return 类型,则从函数返回通用 lambda 表达式会导致编译器警告
Returning a generic lambda expression from a function causes compiler warnings if an explicit return type is given
我有一个函数,其 return 类型是一个简单的通用 lambda 表达式。 (由这个函数编辑的 lambda return 最终作为参数传递给像 std::transform()
或 std::accumulate()
这样的 STL 算法。)
当 lambda 没有明确的 return 类型时,编译器不会发出警告:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) {return dst + src; };
}
当 lambda 具有明确的 return 指定类型时:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) -> decltype(dst) {return dst + src; };
}
两个编译器发出这些类似的警告:
GCC: returning 引用临时 [-Wreturn-local-addr]
MSVC: return局部变量或临时变量的地址
是否应该注意此警告,因为它表明该方法存在缺陷(可能存在未定义的行为!)并且应该进行重构?或者它们是“噪音”?
我无法确定为什么显式指定 return 类型会导致 returned 表达式成为“临时”,否则它不会。请解释,谢谢!
编辑(添加更多上下文):
希望对 lambda 使用 auto
参数是因为 src
和 dst
可能是不同的类型(例如,一个是 std::uint8_t
,一个是 std::uint_16t
),但我希望 return 始终与 dst
参数的类型相同,而不管 src
.
的类型如何
重点是 decltype(dst)
是 auto const &
(您可以在其中看到 auto
作为模板类型`,因此 lambda return a reference(我重复:reference)常量对象。
问题是引用
dst + src
即:对临时值的引用,从操作 dst + src
创建的临时对象,当 lambda 结束执行时,它不再存在。
一个可能的解决方案:删除 -> decltype(dst)
或将其更改为 -> decltype(dst+src)
,这样您 return 一个值,而不是一个引用。
另一种方法(在这种情况下需要更多的打字,但在更复杂的情况下可能更可取)可以从 decltype()
编辑的类型 return 中删除引用部分。
所以
-> std::remove_reference_t<decltype(dst)>
或者,按照 Jarod42 的建议,也
-> std::decay_t<decltype(dst)>
如果dst
的类型支持一元运算符+
(return与dst
的类型相同),另一种简单的解决方案可以是
-> decltype(+dst)
这样,+dst
是一个表达式,而不是变量,所以 decltype(+dst)
不再是引用。
我有一个函数,其 return 类型是一个简单的通用 lambda 表达式。 (由这个函数编辑的 lambda return 最终作为参数传递给像 std::transform()
或 std::accumulate()
这样的 STL 算法。)
当 lambda 没有明确的 return 类型时,编译器不会发出警告:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) {return dst + src; };
}
当 lambda 具有明确的 return 指定类型时:
inline auto AccumulateInto() {
return [](const auto& src, const auto& dst) -> decltype(dst) {return dst + src; };
}
两个编译器发出这些类似的警告:
GCC: returning 引用临时 [-Wreturn-local-addr]
MSVC: return局部变量或临时变量的地址
是否应该注意此警告,因为它表明该方法存在缺陷(可能存在未定义的行为!)并且应该进行重构?或者它们是“噪音”?
我无法确定为什么显式指定 return 类型会导致 returned 表达式成为“临时”,否则它不会。请解释,谢谢!
编辑(添加更多上下文):
希望对 lambda 使用 auto
参数是因为 src
和 dst
可能是不同的类型(例如,一个是 std::uint8_t
,一个是 std::uint_16t
),但我希望 return 始终与 dst
参数的类型相同,而不管 src
.
重点是 decltype(dst)
是 auto const &
(您可以在其中看到 auto
作为模板类型`,因此 lambda return a reference(我重复:reference)常量对象。
问题是引用
dst + src
即:对临时值的引用,从操作 dst + src
创建的临时对象,当 lambda 结束执行时,它不再存在。
一个可能的解决方案:删除 -> decltype(dst)
或将其更改为 -> decltype(dst+src)
,这样您 return 一个值,而不是一个引用。
另一种方法(在这种情况下需要更多的打字,但在更复杂的情况下可能更可取)可以从 decltype()
编辑的类型 return 中删除引用部分。
所以
-> std::remove_reference_t<decltype(dst)>
或者,按照 Jarod42 的建议,也
-> std::decay_t<decltype(dst)>
如果dst
的类型支持一元运算符+
(return与dst
的类型相同),另一种简单的解决方案可以是
-> decltype(+dst)
这样,+dst
是一个表达式,而不是变量,所以 decltype(+dst)
不再是引用。