繁体   English   中英

auto&& 从 C++ lambda 返回类型

[英]auto&& return type from a C++ lambda

我有兴趣了解尾随auto&&返回类型的确切含义,特别是与decltype(auto)的区别,后者在这里不起作用,以及未指定的返回类型,后者也不起作用。

在下面的代码中, fn返回参数的x_字段。 当参数是左值时, x_作为左值返回,等等。

fn_bad[123]的示例中,它似乎返回int ,即使提供了左值参数也是如此。 我明白为什么-> auto会导致这种情况,但我希望-> decltype(auto)返回int& 为什么只能-> auto&&工作?

#include <utility>

struct Foo { int x_; };

int main() {
  auto fn_bad1 = [](auto&& foo) -> decltype(auto) { return std::forward<decltype(foo)>(foo).x_; };
  auto fn_bad2 = [](auto&& foo) -> auto           { return std::forward<decltype(foo)>(foo).x_; };
  auto fn_bad3 = [](auto&& foo)                   { return std::forward<decltype(foo)>(foo).x_; };
  auto fn      = [](auto&& foo) -> auto&&         { return std::forward<decltype(foo)>(foo).x_; };
  Foo a{};
  fn(a) = fn(Foo{100}); // doesn't compile with bad1, bad2, bad3
}

但我希望 -> decltype(auto)返回int&

这是decltype的预期行为,

(强调我的)

检查实体的声明类型表达式的类型和值类别。

1) 如果参数是未加括号的 id-expression 或未加括号的class 成员访问表达式,则 decltype 产生此表达式命名的实体的类型。

因此std::forward<decltype(foo)>(foo).x_decltype(auto)的结果产生数据成员x_的类型,即int

如果您将括号添加为

[](auto&& foo) -> decltype(auto) { return (std::forward<decltype(foo)>(foo).x_); };
//                                        ^                                   ^

然后

2) 如果参数是T类型的任何其他表达式,并且

a) 如果表达式的值类别是 xvalue,则decltype产生T&&
b) 如果表达式的值类别是左值,则decltype产生T&
c) 如果表达式的值类别是纯右值,则decltype产生T

请注意,如果 object 的名称被括号括起来,它会被视为普通的左值表达式,因此decltype(x)decltype((x))通常是不同的类型。

然后,正如您所说,当将左值传递给 lambda 时,表达式(std::forward<decltype(foo)>(foo).x_)是左值,则返回类型将为int& 当传递一个右值时,表达式是一个 xvalue,然后返回类型将是int&& (这可能会导致悬空引用问题)。

对于第二种情况,根据模板参数推导的正常规则,无论何时传递左值或右值,返回类型始终为int

第三种情况与第二种情况相同。

对于第 4 种情况,应用转发引用的特殊规则,则当返回表达式为左值时返回类型为int& ,当返回表达式为右值时返回类型为int&&

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM