当子表达式创建数组时,其中的临时变量会发生什么?

发布于 2024-11-15 11:36:54 字数 929 浏览 1 评论 0原文

我正在阅读 FDIS (12.2p{4,5}) 的这两段:

在两种情况下,临时变量会在与完整表达式结束时不同的点被销毁。第一个上下文是调用默认构造函数来初始化数组的元素时。如果构造函数有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,将按顺序销毁在默认参数中创建的每个临时参数。

第二个上下文是当引用绑定到临时对象时。引用绑定到的临时对象或引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,但以下情况除外: [...]

  • 在函数调用 (5.2.2) 中临时绑定到引用参数将持续存在,直到包含调用的完整表达式完成为止。

对于以下情况,这两者似乎矛盾:

struct A {
  A() { std::cout << "C" << std::endl; }
  ~A() { std::cout << "D" << std::endl; }
};

struct B {
  B(A const& a = A()) { }
};

typedef B array[2];

int main() {
  array{};
}

此输出将按照第一个上下文的要求输出 CDCD,还是将按照第二个上下文的要求输出 CCDD? GCC 似乎遵循第二个上下文描述并输出 CCDD。我是否忽略了一些重要的事情?


编辑:我认为它不需要 C++0x。这个 new 表达式也受到我的问题的影响:

new array(); /* CDCD or CCDD ?? */

但在这种情况下,GCC 遵循第一个上下文,并输出 CDCD。

I was reading these two paragraphs of the FDIS (12.2p{4,5}):

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 a default constructor is called to initialize an element of an array. If the constructor has one or more default arguments, the destruction of every temporary created in a default argument is sequenced before the construction of the next array element, if any.

and

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 except:
[...]

  • A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.

These two two seem to contradict for the following case

struct A {
  A() { std::cout << "C" << std::endl; }
  ~A() { std::cout << "D" << std::endl; }
};

struct B {
  B(A const& a = A()) { }
};

typedef B array[2];

int main() {
  array{};
}

Will this output CDCD as required by the first context, or will this output CCDD as required by the second context? GCC seems to follow the second context description and outputs CCDD. Have I overlooked something important?


EDIT: I don't think it needs C++0x. This new-expression is affected too by my question:

new array(); /* CDCD or CCDD ?? */

In this case though, GCC follows the first context, and outputs CDCD.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丢了幸福的猪 2024-11-22 11:36:54

我不认为这有什么矛盾。

5.2.2 清楚地说明了什么是函数调用。函数调用是后缀表达式,后跟括号
包含一个可能为空的,
以逗号分隔的表达式列表
这构成了论点
功能。

程序中的任何地方似乎都没有对 B::B(A const&) 的函数调用,因此我不知道第二段如何应用。

编辑上面可能是不正确的,考虑到 1.9p10 等。

I don't think there's a contradiction.

5.2.2 clearly says what a function call is. A function call is a postfix expression followed by parentheses
containing a possibly empty,
comma-separated list of expressions
which constitute the arguments to the
function.

There doesn't seem to be a function call to B::B(A const&) anywhere in your program, so I don't see how the second passage applies.

EDIT the above is probably incorrect, given 1.9p10 etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文