不是最重要的常量..但这是什么?

发布于 2024-12-15 11:05:12 字数 623 浏览 5 评论 0原文

这输出 F~ 但我期待 ~F

#include <iostream>

struct Foo {
    int _x;
    operator const int & () const {return _x;}
    ~ Foo () {std :: cout << "~";}
};

void foo (const int &)
{
    std :: cout << "F";
}

int main ()
{
    foo (Foo ());
}

我将其构建为反例,以表明最重要的常量是一个例外而不是规则。通常写为

当 const 引用绑定到临时对象时,该临时对象的生命周期将延长到引用的生命周期

我试图说明的是,虽然 Foo() 是一个临时对象,但对 的引用>_x返回的转换运算符不是,说明上面的代码是不安全的。

但输出似乎证明该示例是安全的,临时 Foo() 的生命周期因对其成员之一的 const 引用的存在而延长。

这是对的吗?标准中哪里规定了这一点?

This outputs F~ but I was expecting ~F

#include <iostream>

struct Foo {
    int _x;
    operator const int & () const {return _x;}
    ~ Foo () {std :: cout << "~";}
};

void foo (const int &)
{
    std :: cout << "F";
}

int main ()
{
    foo (Foo ());
}

I constructed this as a counterexample to show that the most-important-const is an exception rather than a rule. It is normally written as

when a const reference binds to a temporary, then the lifetime of that temporary is extended to the lifetime of the reference

I was trying to illustrate that, although Foo() is a temporary, the reference to _x returned by the conversion operator is not, and that the above code is unsafe.

But the output seems to prove that the example is safe, the lifetime of the temporary Foo() is extended by the existence of a const reference to one of its members.

Is this right? Where in the standard is this specified?

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

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

发布评论

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

评论(4

沉默的熊 2024-12-22 11:05:12

关于临时对象的一般规则是,当它们成为结束的完整表达式的一部分时(非正式地,当到达 ; 时),它们的生命就结束了。

12.2 临时对象

3/ [...] 临时对象在评估完整表达式 (1.9) 的最后一步被销毁,该完整表达式 (1.9)(在词法上)包含创建它们的点。即使该评估最终引发异常也是如此。销毁临时对象的值计算和副作用仅与完整表达式相关,而不与任何特定子表达式相关。

The general rule, regarding temporaries, is that their life ends when the full expression they are part of ends (informally, when reaching the ;).

12.2 Temporary objects

3/ [...] Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception. The value computations and side effects of destroying a temporary object are associated only with the full-expression, not with any specific subexpression.

活雷疯 2024-12-22 11:05:12

这是因为临时变量在函数调用的整个过程中都存在。当您执行 foo (Foo ()); 时,会发生以下情况:

  1. 临时 Foo 被构造,然后
  2. 在临时对象上调用 operator const int&
  3. 一旦foo() 返回,foo() 被调用,并且输出 F
  4. 临时 Foo 被销毁,并且输出 <代码>~

That's because the temporary survives for the whole duration of function call. When you do foo (Foo ()); here's what happens:

  1. temporary Foo is contructed, then
  2. operator const int& is called on the temporary
  3. foo() is called and this outputs F
  4. once foo() returns temporary Foo is destroyed and this outputs ~
尐偏执 2024-12-22 11:05:12

这里没有魔法。所有函数参数都位于调用者的范围内,包括临时参数。临时 Foo() 在调用者的范围内构造,并在行尾销毁。

因此,无论函数 foo() 做什么,都发生在 main() 中的参数被销毁之前。

There's no magic here. All function arguments live in the scope of the caller, including temporaries. The temporary Foo() is constructed in the scope of the caller, and destroyed at the end of the line.

So whatever the function foo() does happens before its arguments in main() are destroyed.

半世蒼涼 2024-12-22 11:05:12

但是这里的 Foo 实例始终会存在,直到分号结束创建它的语句为止。将对成员的引用传递到函数调用中并没有改变这一点。

尝试:

int const &ref = Foo();
foo(ref);

对比

Foo const &ref = Foo(); // or function returning temp
foo(ref);

But your Foo instance here was always going to live until the semicolon ending the statement in which it was created. Passing a reference to a member into a function call didn't change that.

Try:

int const &ref = Foo();
foo(ref);

versus

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