当初始化器临时被破坏了? [英] When exactly is an initializer temporary destroyed?

查看:133
本文介绍了当初始化器临时被破坏了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天在回答了一些问题后构建了这个实验。

  struct A {
bool& b;
A(bool& b):b(b){}
〜A(){std :: cout< b; }
bool yield(){return true; }
};

bool b = A(b).yield();

int main(){}

b在动态设置为 true 之前,有值 false 初始化。如果临时在 b 初始化之前被销毁,我们将打印 false ,否则 true



规范说,临时数据在完全表达式的末尾被销毁。这似乎不是与 b 的初始化排序。所以我不知道




  • 规范允许实现打印 false code> true 在不同的运行中?



/ code>,而GCC打印 true 。这让我困惑。

解决方案

我认为它允许输出true或false,



真或假部分是(如你所说),临时 A 对于 b 的动态初始化没有排序。



所有的可能性是因为 b 的初始化不是关于 std :: cout 的创建/初始化的顺序;当你尝试销毁临时, cout 可能尚未创建/初始化,所以试图打印的东西可能不工作在所有的点。



编辑:至少,请参阅以下顺序:



/ p>

Edit2:重新读取§12.2/ 4(再一次)后,我又改变了图表。 §12.2/ 4说:


有两个上下文,其中临时表在与完整表达式结束不同的点被销毁。第一个上下文是一个表达式作为定义对象的声明器的初始化器。在这种情况下,保存表达式结果的临时变量应该持续到对象的初始化完成。对象从临时的副本初始化;在这个复制期间,一个实现可以多次调用拷贝构造函数;


我相信这个表达式是一个声明器的初始化器定义一个对象,所以它需要从表达式( true ,在这种情况下)的值的副本初始化对象,而不是直接从返回值。在 true 的情况下,这可能是一个没有区别的区别,但我认为这个图在技术上比现在更准确。



这也很清楚(我认为)暂时保持 true 不会



这部分在C ++ 0x / C ++ 11中已经不存在了。 ,所以我重新绘制了图表(再一次),以显示两者之间的差异(以及在C ++ 11中得到的简单多少)。


I constructed this experiment today, after answering some question

struct A { 
  bool &b; 
  A(bool &b):b(b) { } 
  ~A() { std::cout << b; }  
  bool yield() { return true; } 
}; 

bool b = A(b).yield();

int main() { }

b has value false (resulting from zero initialization) before setting it to true by the dynamic initialization. If the temporary is destroyed before initialization of b finished, we will print false, otherwise true.

The spec says that the temporary is destroyed at the end of the full-expression. That does not seem to be ordered with the initialization of b. So I wonder

  • Does the spec allow an implementation to print both false and true in different runs?

Clang prints false for the above, while GCC prints true. This confuses me. Did I miss some spec text defining the order?

解决方案

I think it's allowed to print out true, or false, or for somewhat unrelated reasons, nothing at all.

The true or false part is (as you've said), that the destruction of the temporary A object is not ordered with respect to the dynamic initialization of b.

The nothing at all possibility is because the initialization of b is not ordered with respect to the creation/initialization of std::cout; when you try to destroy the temporary, cout may not have been created/initialized yet, so attempting to print something may not work at that point at all. [Edit: this is specific to C++98/03, and does not apply to C++11.]

Edit: here is how I, at least, see the sequence:

Edit2: After rereading §12.2/4 (yet again), I've changed the diagram again. §12.2/4 says:

There are two contexts in which temporaries are destroyed at a different point than the end of the full expression. The first context is when an expression appears as an initializer for a declarator defining an object. In that context, the temporary that holds the result of the expression shall persist until the object’s initialization is complete. The object is initialized from a copy of the temporary; during this copying, an implementation can call the copy constructor many times; the temporary is destroyed after it has been copied, before or when the initialization completes.

I believe this expression is an initializer for a declarator defining an object, so it's required to initialize the object from a copy of the value of the expression (true, in this case), not directly from the return value. In the case of true, this is probably a distinction without a difference, but I think the diagram is technically more accurate as it stands right now.

This also makes fairly clear (I think) that the temporary holding true does not have to be destroyed at the end of the full expression, so I've re-drawn the diagram to reflect that as well.

This section is gone in C++0x/C++11, so I've re-drawn the diagram (yet again) to show the difference between the two (and how much simpler this piece has gotten in C++11).

这篇关于当初始化器临时被破坏了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆