非const引用是否会延长临时对象的寿命?
Do *non*-const references prolong the lives of temporaries?
以前,我认为这样的代码会失败:
const MyClass& obj = MyClass();
obj.DoSomething();
,因为MyClass对象将在其完整表达式结束时被销毁,使obj成为悬空引用。然而,我(在这里)了解到这不是真的;该标准实际上有一个特殊的规定,允许const引用保持临时存在,直到所述引用自己被销毁。但是,需要强调的是,只有const引用具有这种功能。今天我在VS2012中运行了下面的代码作为实验。
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()
时的输出为:
ctor
Hello world
dtor
所以我看了看c++ 11标准草案,只发现了这个(§12.2/4):
有两种上下文中,临时值在a处被销毁不同的点比结束的充分表达。第一个上下文没有应用)。第二个上下文是当引用绑定到暂时的。对象绑定到的临时对象对象所指向的子对象的完整对象引用被绑定,在引用的生命周期内持续存在。
上面明显没有const
这个词。所以;这种行为是否已更改为c++ 11,我错了关于const
的事情开始,或者VS2012有一个错误,我只是没有找到标准的相关部分?
行为没有改变,您只需要将警告级别提高到/W4
。VisualStudio甚至将非const
左值引用作为编译器扩展来实现生存期扩展规则。在这种情况下,将右值绑定到非const
引用的行为与将其绑定到const
引用的行为相同。
使用/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
左值引用的文本可以在§8.5.3/5
本;否则,该引用应为对非易失性
const
类型的左值引用(即cv1应为)const
),否则引用必须是右值引用。
(例子: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]
引用语句的后半部分允许将临时值绑定到右值引用,如lib的答案所示。
string &&s = string("hello");
这与§12.2/5中的生存期扩展规则相结合,意味着临时对象的生存期现在将匹配它所绑定的(rvalue)引用的生存期。
本节中从未出现过const
这个词。规则一直是(从我记事起)用于初始化引用的临时变量有其生存期扩展以匹配引用的类型,而不考虑类型参考文献。
在20世纪80年代末的某个时候(非常标准之前),c++被引入不能使用临时对象初始化的规则非const引用。初始化非const引用临时的仍然会延长生命周期(大概),但是既然你做不到……大多数编译器实现一个过渡时期,在此期间,这样的初始化只会发出警告(并延长生存期)。
由于某种原因,当微软最终决定实现c++(在20世纪90年代早期),他们决定不这么做实现新规则,并允许初始化带有临时(甚至没有警告)的非const引用,在大多数其他供应商逐渐转向的时候警告为错误)。当然,它实现了通常的生命周期规则。
最后,在c++ 11中引入了新的引用类型,哪个允许(甚至需要)初始化一个临时的。关于临时工寿命的规则没有改变,虽然;一个用于初始化的临时对象一个引用(不管引用的类型是什么)都有它的寿命延长。
(有几个例外:我不建议使用临时的在初始化中初始化类成员引用列表。)
不,因为右值引用不需要是const
,所以标准引号是正确的
string &&s = string("hello");
寿命仍然增大。使代码对非const左值引用无效的约束是在第8条(请注意,这不是在您引用的段落中添加"const"answers"右值引用"等的正确位置。您需要主动拒绝这些绑定,而不仅仅是说这些绑定的生命周期没有延长,因为您将使绑定本身保持良好形式)。
- 在不复制临时对象的情况下延长其生存期
- 为什么当我们有常量引用时创建临时对象?
- 程序如何'remember'临时对象?
- 返回对临时对象的引用
- 防止临时对象文件访问 MSVC 中的磁盘
- 对临时对象的Const引用不会延长其生存期
- 编译器在 const ref 类型参数上使用临时对象时是否应该警告不安全的行为?
- C++17:是编译器为(静态存储持续时间)const引用绑定创建的可修改的临时对象(和存储)
- C++ const&绑定到临时对象
- 临时对象和非const参考
- const引用是否延长临时对象返回的临时对象的寿命
- 三元运算符和通过引用const延长临时对象的生存期
- 为什么我构建的临时对象const不可变
- 返回对临时对象成员的const引用
- c++临时对象绑定到实参并返回const引用值
- 为什么const限定符允许临时对象或右值
- 与const引用(方法链)相关联的临时对象的生命周期
- 在循环中用作"const &"函数参数的临时对象的编译器优化?
- 对临时对象的const引用进行const强制转换会导致未定义行为吗?
- 非const引用是否会延长临时对象的寿命?