简体   繁体   English

为什么对整数的右值引用是合法的

[英]Why is rvalue reference to an integer legal

This might be a dumb question about C++11 but it really bothers me.这可能是一个关于 C++11 的愚蠢问题,但它确实困扰着我。

As my understanding, rvalue reference is also a reference, which means that it will algo point to some variable, just like the reference does.根据我的理解,右值引用也是一个引用,这意味着它会像引用一样指向某个变量。

For example,例如,

const int &ref = 1;

The reference ref points to the pure rvalue 1 , which can't be modified, that's why the compiler force us to use const .引用ref指向纯右值1 ,无法修改,这就是编译器强制我们使用const

Another example,另一个例子,

Bar&& GetBar()
{
    Bar b;
    return std::move(b);
}

This function will return a dangling reference because b is destructed after return ing.此函数将返回一个悬空引用,因为breturn ing 后被破坏。

In a word, rvalue reference is algo a reference.总之,右值引用就是一个引用。

Now I'm confused.现在我很困惑。 Please check the following code:请检查以下代码:

int &&rref = 1;

If rvalue reference is also a reference, so rref now points to the pure rvalue 1 , which shouldn't be compilable as my understanding, because if it's compilable, what if I execute rref = 2 ?如果右值引用也是引用,那么rref现在指向纯右值1 ,按照我的理解,它不应该是可编译的,因为如果它是可编译的,那么如果我执行rref = 2呢? Does this mean that the pure rvalue is changed: 1 becomes 2 ?这是否意味着纯右值已更改: 1变为2

But gcc told me that it was compilable...但是 gcc 告诉我它是可编译的...

Why?为什么? Why don't we need const int &&rref = 1 ?为什么我们不需要const int &&rref = 1

A quote from cppreference来自cppreference的引用

The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11), see reference initialization for details.临时对象的生命周期可以通过绑定到 const 左值引用或右值引用(C++11 起)来扩展,详情参见引用初始化。

With a link to additional details here 此处提供其他详细信息的链接

Whenever a reference is bound to a temporary or to a subobject thereof, the lifetime of the temporary is extended to match the lifetime of the reference, with the following exceptions:每当引用绑定到临时对象或其子对象时,临时对象的生命周期都会延长以匹配引用的生命周期,但以下情况除外:

It then goes on to list a few exceptions like然后继续列出一些例外情况,例如

a temporary bound to a return value of a function in a return statement is not extended: it is destroyed immediately at the end of the return expression. return 语句中函数返回值的临时绑定不会被扩展:它会在 return 表达式结束时立即销毁。 Such function always returns a dangling reference.这样的函数总是返回一个悬空引用。

a temporary bound to a reference member in a constructor initializer list persists only until the constructor exits, not as long as the object exists.临时绑定到构造函数初始值设定项列表中的引用成员仅持续到构造函数退出,而不是只要对象存在。 (note: such initialization is ill-formed as of DR 1696). (注意:从 DR 1696 开始,这种初始化格式不正确)。 (until C++14) (直到 C++14)

a temporary bound to a reference parameter in a function call exists until the end of the full expression containing that function call: if the function returns a reference, which outlives the full expression, it becomes a dangling reference.函数调用中引用参数的临时绑定一直存在,直到包含该函数调用的完整表达式结束:如果函数返回一个引用,该引用的生命周期超过完整表达式,则它成为悬空引用。

a temporary bound to a reference in the initializer used in a new-expression exists until the end of the full expression containing that new-expression, not as long as the initialized object.临时绑定到 new 表达式中使用的初始值设定项中的引用一直存在,直到包含该 new 表达式的完整表达式结束,而不是与初始化对象一样长。 If the initialized object outlives the full expression, its reference member becomes a dangling reference.如果初始化的对象比完整表达式的生命周期长,则其引用成员将成为悬空引用。 (since C++11) (C++11 起)

a temporary bound to a reference in a reference element of an aggregate initialized using direct-initialization syntax (parentheses) as opposed to list-initialization syntax (braces) exists until the end of the full expression containing the initializer.使用直接初始化语法(括号)而不是列表初始化语法(大括号)初始化的聚合的引用元素中的引用的临时绑定一直存在,直到包含初始化程序的完整表达式结束。 (since C++20) (C++20 起)

So the reasoning that所以推理是

const int &ref = 1;

works since we use const is not true.有效,因为我们使用const是不正确的。 The compiler is actually extending the lifetime of the temporary object to match the lifetime of the reference.编译器实际上是在延长临时对象的生命周期以匹配引用的生命周期。 So it's equally valid to do the same thing with an rvalue reference.所以用右值引用做同样的事情同样有效。

On the other hand另一方面

int &ref = 1;

would not make sense since 1 is not an lvalue.没有意义,因为1不是左值。 That's why we need const or an rvalue reference.这就是我们需要const或右值引用的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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