
[英]Why decltype((i)) is reference type but decltype(i+0) is int type?
[英]Why is the result of “decltype(i+j)” not an rvalue reference?
我试图给出一个导致rvalue的操作的简单示例。
这个测试用例应该有效,但令人惊讶的是(对我而言),添加两个int
的结果不是rvalue(引用)。 我在这里错过了什么?
void test(int i, int j)
{
// this assert should pass, but fails:
static_assert(std::is_same<decltype(i + j), int&&>(), "i + j should be a rvalue");
// this assert passed, but should fail:
static_assert(std::is_same<decltype(i + j), int>(), "this assert should fail...");
}
i + j
是一个prvalue表达式 ,
prvalue(“纯rvalue”)表达式是一个没有标识且可以从中移出的表达式。
a + b,a%b,a&b,a << b,以及所有其他内置算术表达式;
不是xvalue ,
xvalue(“expiring value”)表达式是一个具有标识并可以从中移出的表达式。
并且decltype说明符为prvalue产生T
,而不是T&&
。
a)如果表达式的值类别是xvalue,则decltype产生T &&;
b)如果表达式的值类别是左值,则decltype产生T&;
c)如果表达式的值类别是prvalue,则decltype产生T.
您可以通过std::move
其设为xvalue:
static_assert(std::is_same<decltype(std::move(i + j)), int&&>(), "std::move(i + j) is a xvalue then this static_assert won't fail");
基于@ songyuanyao的答案 ,我注意到我的错误是检查错误的东西:我的目的是检查i+j
的结果是否会绑定到右值引用,但我检查它是否是右值引用。
decltype基于值类别推断类型,而不是基于值将绑定到的 引用类型 :
1)如果表达式的值类别是
xvalue
,则decltype产生T&&
;
2)如果表达式的值类别是lvalue
,则decltype产生T&
;
3)如果表达式的值类别是prvalue
,则decltype产生T
如列表所示, 自C ++ 11以来, rvalues
不是最低级别的独特类别。 它们现在是一个复合类别,包含prvalues
和xvalues
。 写的问题询问表达式是否是rvalue reference
并检查它是否是xvalue
。
从上面的列表中可以看出, i+j
是一个prvalue
,所以第三种情况适用。 这解释了为什么decltype(i + j)
是int
而不是int&&
。 xvalues
和prvalues
绑定到右值引用。
因此,通过检查i+j
是否绑定到lvalue reference
或rvalue reference
确认它确实绑定到 rvalue reference
:
void foo(const int& f)
{
std::cout << "binds to lvalue reference" << std::endl;
}
void foo(int&& f)
{
std::cout << "binds to rvalue reference" << std::endl;
}
void test(int i, int j)
{
foo(i); // lvalue -> lvalue ref
foo(std::move(i)); // xvalue -> rvalue ref
// (std::move converts the argument to a rvalue reference and returns it as an xvalue)
foo(i + j); // prvalue -> rvalue ref
}
总之: i+j
不是右值参考,但它与一个结合 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.