Do * non * -const参考是否延长了临时性的生命? [英] Do *non*-const references prolong the lives of temporaries?
问题描述
一次,我认为这样的代码会失败:
Once upon a time, I assumed that code like this would fail:
const MyClass& obj = MyClass();
obj.DoSomething();
,因为MyClass对象将在其full-expression结尾处被销毁,使obj成为悬挂参考。然而,我(在这里)学到这不是真的;标准实际上有一个特殊的规定,允许const引用保持临时存活,直到所述引用自己被销毁。但是,强调的是,只有 const 引用有这个权力。今天我在VS2012中运行下面的代码作为一个实验。
because the MyClass object would be destroyed at the end of its full-expression, leaving obj as a dangling reference. However, I learned (here) that this isn't true; the standard actually has a special provision that allows const references to keep temporaries alive until said references are destroyed themselves. But, it was emphasized, only const references have this power. Today I ran the code below in VS2012 as an experiment.
struct Foo
{
Foo() { std::cout << "ctor" << std::endl; }
~Foo() { std::cout << "dtor" << std::endl; }
};
void f()
{
Foo& f = Foo();
std::cout << "Hello world" << std::endl;
}
调用 f c $ c>是:
The output when calling f()
was:
ctor
Hello world
dtor
所以我看了一下C ++ 11草案标准,只找到了这个(§12.2 / 4):
So I had a look at the C++11 draft standard, and only found this (§ 12.2/4):
有两个上下文,其中临时表在与完全表达式的结尾不同的
处被销毁。第一个上下文[不适用
]。第二个上下文是当引用绑定到
临时时。引用绑定到的临时变量或
临时变量(
引用绑定的子对象的完整对象)在引用的生命周期内仍然存在。
There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context [doesn't apply]. The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference.
上面显然没有单词 const
。所以;有这个行为被改变为C ++ 11,是我错了关于 const
开始,或VS2012有一个错误,我只是没有找到相关部分标准?
The word const
is conspicuously absent from the above. So; has this behavior been changed for C++11, was I wrong about the const
thing to begin with, or does VS2012 have a bug and I just haven't found the relevant part of the standard?
推荐答案
行为没有改变,你只需要将你的警告级别更改为 / W4
。 VisualStudio实现了生存期扩展规则,即使对于非 - const
lvalue引用作为编译器扩展。在这种情况下,将右值绑定到非 - const
引用的行为与将它绑定到 const
参考。
The behavior hasn't changed, you just need to turn your warning level up to /W4
. VisualStudio implements the lifetime extension rule even for non-const
lvalue references as a compiler extension. In this context, binding an rvalue to the non-const
reference behaves the same as if you were binding it to a const
reference.
使用 / W4
,您会看到:
warning C4239: nonstandard extension used : 'initializing' : conversion from 'Foo' to 'Foo &'
1> A non-const reference may only be bound to an lvalue
不允许将右值绑定到非 const
lvalue reference可以在
The text disallowing binding of an rvalue to a non-const
lvalue reference can be found in §8.5.3/5
—否则,引用将是对非易失性
const
类型的左值引用(即,cv1 应为
const
),或引用应为右值引用。
[示例:
— Otherwise, the reference shall be an lvalue reference to a non-volatile
const
type (i.e., cv1 shall beconst
), or the reference shall be an rvalue reference.
[ Example:
double& rd2 = 2.0; // error: not an lvalue and reference not const
int i = 2;
double& rd3 = i; // error: type mismatch and reference not const
- end example]
—end example ]
引用语句的后半部分允许将临时数据绑定到右值引用,如 litb的回答。
The second half of the quoted statement is what allows binding of a temporary to an rvalue reference, as shown in litb's answer.
string &&s = string("hello");
结合§12.2/ 5 意味着临时的生命周期现在将匹配它绑定到的(右值)引用的生存期。
This, combined with the lifetime extension rule in §12.2/5, means the lifetime of the temporary will now match the lifetime of the (rvalue) reference it is bound to.
这篇关于Do * non * -const参考是否延长了临时性的生命?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!