E_G*_*E_G 3 c++ decltype auto c++11 c++14
我很想了解尾随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
}
Run Code Online (Sandbox Code Playgroud)
但我希望 ->
decltype(auto)返回int&
这是 的预期行为decltype,
(强调我的)
检查实体的声明类型或表达式的类型和值类别。
1) 如果参数是无括号的 id-expression 或无括号的类成员访问表达式,则 decltype 产生由此表达式命名的实体的类型。
所以decltype(auto)on的结果是std::forward<decltype(foo)>(foo).x_数据成员的类型x_,即int。
如果您将括号添加为
[](auto&& foo) -> decltype(auto) { return (std::forward<decltype(foo)>(foo).x_); };
// ^ ^
Run Code Online (Sandbox Code Playgroud)
然后
2) 如果参数是任何其他类型的表达式
T,并且a) 如果表达式的值类别是 xvalue,则
decltypeyieldT&&;
b) 如果表达式的值类别是左值,则decltype产生T&;
c) 如果表达式的值类别是纯右值,则decltype产生T。请注意,如果一个对象的名称被加括号,它是作为一个普通的左值表达式处理,从而
decltype(x)与decltype((x))通常不同的类型。
然后,正如您所说,当将左值传递给 lambda 时,表达式(std::forward<decltype(foo)>(foo).x_)是一个左值,那么返回类型将是int&; 当传递一个右值时,表达式是一个 xvalue,然后返回类型将是int&&(这可能会导致悬空引用问题)。
对于第二种情况,根据模板参数推导的正常规则,每当传递左值或右值时,返回类型始终为int。
第 3 种情况与第 2 种情况相同。
对于第 4 种情况,应用了转发引用的特殊规则,那么返回类型将是int&当返回表达式为左值时,int&&当返回表达式为右值时。
| 归档时间: |
|
| 查看次数: |
166 次 |
| 最近记录: |