const引用临时奇偶性 [英] const reference to temporary oddity

查看:169
本文介绍了const引用临时奇偶性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们都知道这样的东西在c ++中是有效的:

We all know that things like this are valid in c++:

const T &x = T();

while:

T &x = T();

不是。

href =http://stackoverflow.com/questions/3097593/what-happens-when-c-reference-leaves-its-scope/>最近的问题对话导致此规则。 OP已经发布了一些清楚地唤起UB的代码。但我会期望它的修改版本工作(这是修改版本):

In a recent question the conversation lead to this rule. The OP had posted some code which clearly evokes UB. But I would have expect a modified version of it to work (This is the modified version):

#include <iostream>
using namespace std;

class A {
public:
    A(int k) { _k = k; };
    int get() const { return _k; };
    int _k;
};

class B {
public:
    B(const A& a) : _a(a) {}
    void b() { cout << _a.get(); }
    const A& _a;
};

B* f() {
    return new B(A(10));
}

int main() {
    f()->b();
}

在某些机器上打印垃圾,其他机器上打印垃圾10 ...对我来说 :-)。但是后来我想, A 基本上是一个荣耀的 int 它初始化一个并读它。为什么不直接调用 A a int ,看看会发生什么:

This prints garbage on some machines, 10 on others... sounds like UB to me :-). But then I thought, well A is basically a glorified int all it does it initialize one and read it. Why not just call A an int and see what happens:

#include <iostream>
using namespace std;

typedef int A;

class B {
public:
    B(const A& a) : _a(a) {}
    void b() { cout << _a; }
    const A& _a;
};

B* f() {
    return new B(A(10));
}

int main() {
    f()->b();
}

它输出 10 每次。至少似乎像const引用规则对 int 版本有效,但不是类版本。他们都是简单的UB由于使用堆?我只是幸运的 int 版本,因为编译看到所有 const s,只是直接打印出一个 10

It prints 10 every time. It at least seems like the const reference rule is in effect for the int version, but not for the class version. Are they both simply UB due to the use of the heap? Am I just lucky with the int version because the compile saw through all consts and just directly printed out a 10? Which aspect of the rule am I missing?

推荐答案

它只是表明通过在编译器中尝试来分析语言行为通常不会产生任何有用的结果。两个示例都因为同样的原因是无效的。

It simply demonstrates that analyzing language behavior by "trying it in the compiler" doesn't normally produce any useful results. Both of your examples are invalid for the very same reason.

临时的生命周期只有当你使用该临时作为一个const引用的直接初始化器将在引用和临时之间建立一个生命周期链接。

The lifetime of the temporary is only extended when you use that temporary as the direct initializer for a const reference - only that will establish a "lifetime" link between the reference and the temporary.

尝试传递一个临时作为构造函数的参数,并在构造函数中附加一个const引用不会建立

Trying to pass a temporary as a constructor's argument and attaching a const reference inside the constructor will not establish the aforementioned link and will not extend the lifetime of the temporary.

此外,根据C ++标准,如果您这样做

Also, in accordance with C++ standard, if you do this

struct S {
  const int &r;

  S() : r(5) {
    cout << r; // OK
  }
};

临时的生命周期只会扩展到构造函数的结尾。一旦构造函数完成,临时模块,意味着

the lifetime of the temporary is only extended to the end of the constructor. Once the constructor is finished, the temporary dies, meaning that this

S s;
cout << s.r; // Invalid

无效。

您的实验 int 只是似乎工作,纯粹是意外。

Your experiment with int simply "appears to work", purely by accident.

这篇关于const引用临时奇偶性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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