繁体   English   中英

为什么“decltype(i + j)”的结果不是右值参考?

[英]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不是最低级别的独特类别。 它们现在是一个复合类别,包含prvaluesxvalues 写的问题询问表达式是否是rvalue reference并检查它是否是xvalue

从上面的列表中可以看出, i+j是一个prvalue ,所以第三种情况适用。 这解释了为什么decltype(i + j)int而不是int&& xvaluesprvalues 绑定到右值引用。

因此,通过检查i+j是否绑定到lvalue referencervalue 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.

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