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

问题描述 投票:0回答:1

我有兴趣了解一下,尾部的 auto&& 返回型是指,具体来说,与 decltype(auto)在这里是不行的,还有一个未指定的返回类型,也是不行的。

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

的例子中。fn_bad[123],它似乎返回 int即使提供了lvalue参数,也是如此。我知道为什么 -> 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
}
c++ c++11 c++14 c++17
1个回答
4
投票

但我以为-> decltype(auto) 会返回 int&

这是预期的行为 decltype,

(重点是我)

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

1) 如果参数是一个未加括号的id表达式或一个 未括号的类成员访问表达式,那么decltype就会产生这个表达式所命名的实体的类型。

所以这个表达式的结果是 decltype(auto) 关于 std::forward<decltype(foo)>(foo).x_ 产生数据成员的类型 x_即: int.

如果你加上括号,如

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

然后

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

a) 如果 表情 是x值,那么 decltype 产量 T&&b) 如果 表情 是l值,那么 decltype 产量 T&c) 如果 表情 是prvalue,那么 decltype 产量 T.

请注意,如果一个对象的名称被括号括起来,它将被视为一个普通的l-value表达式,所以 decltype(x)decltype((x)) 往往是不同的类型。

然后,正如你所说,当向lambda传递一个lvalue时,表达式为 (std::forward<decltype(foo)>(foo).x_) 是一个l值,那么返回的类型将是 int&当传入一个rvalue的表达式是xvalue时,返回类型将是 int&& (这可能会造成悬空引用的麻烦)。

对于第2种情况,根据一般的规则 模板引论每当传递lvalue或rvalue时,返回类型始终是 int.

第3种情况与第2种情况相同。

对于第4种情况,特殊规则为 转发参考 应用,那么返回类型将是 int& 当返回表达式为lvalue时,以及 int&& 当返回表达式为rvalue时。

© www.soinside.com 2019 - 2024. All rights reserved.