哪个标准措辞告诉我们,ref-to-const 临时寿命延长只"有效一次"?
Which standard wording tells us that ref-to-const temporary lifetime extension only "works once"?
我在聊天中看到了以下示例:
#include <iostream>
struct foo { ~foo() { std::cout << "destroying!n"; } };
const foo& func(const foo& a, const foo&) { return a; }
int main()
{
foo x;
const foo& y = func(foo(), x);
std::cout << "mainn";
}
输出:
destroying!
main
destroying!
它似乎证明了foo
临时的生存期并没有扩展到整个main
,即使它在该范围内绑定到了-const
的引用。
那么,可以推测,寿命延长只"有效一次";也就是说,它在初始化func
的参数时应用,但不会通过连续绑定传递。
我的解释正确吗?如果是这样(如果任何单独的段落直接适用),定义这种行为的标准措辞是什么?
你几乎是对的。这种行为实际上特别来自函数调用,而不是因为任何类型的"只工作一次"规则。
以下是终身延长"功能"的措辞,相关规则用粗体强调:
[C++11: 12.2/5]:
[..]引用绑定到的临时对象或作为引用绑定到子对象的完整对象的临时对象在引用的生存期内持续存在,除外:
- [..]
- 函数调用(5.2.2)中与引用参数的临时绑定将持续存在,直到包含该调用的完整表达式完成为止
- [..]
这是两个问题报告的主题,http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1299和http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1568。
我是前一期报告的记者,该报告旨在涵盖所有这些引用绑定到临时对象的情况,但不打算延长其使用寿命。问题正文中的描述只提到prvalues与临时表达式混淆(这些表达式实际上决定了它们评估对象的生存期是否延长)。但是lvalue和xvalues同样与标准中的混淆。在static_cast
的上下文中发生这种情况的一个例子是问题编号#1568(其中"临时变量"的使用进一步混淆了问题)。
事实上,这个:
函数调用(5.2.2)中引用参数的临时绑定将持续存在,直到包含该调用的完整表达式完成为止。
与同一段落中的其他规则相矛盾。因为临时绑定到函数调用中的引用参数和本地自动引用变量。
这里适用的规则是常识。标准是措辞拙劣,事实上确实保证了这一点。但是没有实现它的实用方法。
可能我有点慢,但对我来说,阅读其他答案并不能清楚这个问题的解决方案。因此,我修改了显示的代码,并希望为其他人总结:答案是,如果访问y
,您将得到未定义的行为!
运行此代码:
struct foo {
int id;
foo(int id) : id(id) { std::cout << "ctor " << id << std::endl; };
~foo() { std::cout << "dtor " << id << std::endl; }
};
const foo& func(const foo& a, const foo&) { return a; }
int main(int argc, char** argv) {
foo x(1);
const foo& y = func(foo(2), x);
std::cout << "main " << y.id << std::endl;
return 0;
}
我的输出是:
ctor 1
ctor 2
dtor 2
main 2
dtor 1
但是线main 2
是未定义的行为。
- 我是否需要在下一次转移时将所有权*转移回转移队列
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 在C++中一次将矢量值写入多个文件
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 为什么 zlib 放气初始化调用一次不起作用?
- 在一次迭代中从 txt 文件中读取多行
- 为什么无论你输入什么,这"while(cin.get(str,3))"只运行一次?
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 高级选择排序 - 在一次迭代中搜索两个元素
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 如何仅使用一次固定<<设置精度(2)?或者至少恢复到默认行为?
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 搜索字符串是否至少包含一次从 0 到 9 的所有数字的最有效方法
- 将CMAKE_CXX_FLAG设置在父目录中一次,并在子目录中有效
- 抓住C++中仅有效一次的锁
- 每秒执行一次的函数,它是有效的,但喜欢每0.5秒执行一次
- 一个有效的方法,随机选择std::vector的所有元素正好一次而不重新洗牌
- 哪个标准措辞告诉我们,ref-to-const 临时寿命延长只"有效一次"?
- 在堆栈上分配一个小对象比在堆上创建它(一次)更有效吗