and*_*ras 17 c++ rvalue decltype rvalue-reference c++11
我试图给出一个导致rvalue的操作的简单示例.
这个测试用例应该有效,但令人惊讶的是(对我而言),添加两个ints 的结果不是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...");
}
Run Code Online (Sandbox Code Playgroud)
son*_*yao 33
i + j是一个prvalue表达式,
prvalue("纯rvalue")表达式是一个没有标识且可以从中移出的表达式.
a + b,a%b,a&b,a << b,以及所有其他内置算术表达式;
不是xvalue,
xvalue("expiring value")表达式是一个具有标识且可以从中移出的表达式.
和decltype说明符产生Tprvalue,而不是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");
Run Code Online (Sandbox Code Playgroud)
基于@ songyuanyao的答案,我注意到我的错误是检查错误的东西:我的意图是检查结果是否i+j会绑定到右值引用,但我检查它是否是右值引用.
decltype 基于值类别推断类型,而不是基于值将绑定到的引用类型:
1)如果表达式的值类别是
xvalue,则decltype产生T&&;
2)如果表达式的值类别是lvalue,则decltype产生T&;
3)如果表达式的值类别是prvalue,则decltype产生T.
如列表所示,自C++ 11以来,rvalues不存在于最低级别的独特类别.他们现在既含有复合类prvalues以及xvalues.写的问题询问表达式是否为a rvalue reference并检查它是否为a xvalue.
从上面的列表中可以清楚地看出i+j是a 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
}
Run Code Online (Sandbox Code Playgroud)
结论: i+j是不是一个右值引用,但它绑定到一个.
| 归档时间: |
|
| 查看次数: |
5292 次 |
| 最近记录: |