c – 安置新的休息时间和参考?

前端之家收集整理的这篇文章主要介绍了c – 安置新的休息时间和参考?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
my answerthis question讨论之后,显然:

允许以下代码

struct Foo {
    int x;
};

Foo f;
Foo & f_ref = f;

(&f) -> ~Foo ();
new (&f) Foo ();

int x = f_ref .x;

但不允许使用以下代码

struct Foo {
    const int & x;           // difference is const reference
    Foo (int & i) : x(i) {}
};

int i;
Foo f (i);
Foo & f_ref = f;

(&f) -> ~Foo ();
new (&f) Foo (i);

int x = f_ref .x;

因为$3.8/7

If,after the lifetime of an object has ended and before the storage which the object occupied is reused or released,a new object is created at the storage location which the original object occupied,a pointer that pointed to the original object,a reference that referred to the original object,or the name of the original object will automatically refer to the new object and,once the lifetime of the new object has started,can be used to manipulate the new object,if:

  • the type of the original object is not const-qualified,and,if a class type,does not contain any non-static data member whose type is const-qualified or a reference type

我可以理解当f不再存在时,如何对fx的引用无效,但是我不明白为什么f_ref应该被纯化,因为它的一个成员是const和/或引用而不是其他:它是对a的引用Foo之前​​并且之后是对Foo的引用.

有人可以解释这种情况背后的理由吗?

编辑

谢谢你的回答.我不会购买“保证它不会改变”这一论点,因为我们目前不允许优化器缓存重新参与,例如:

struct Foo {
    const int & x;
    Foo (const int & i) : x(i) {}
    void do_it ();
};

int i;
Foo f (i);
const int & ii = f.x;

f .do_it (); // may modify i
std :: cout << ii; // May NOT use cached i

我不知道如何允许do_it使引用值无效但是operator new不是 – Sequence points invalidate cached values:为什么要删除/ placement-new是免除的?

解决方法

我相信动机是允许编译器缓存const对象的值(注意const对象,而不仅仅是指向const和引用到const的指针),以及引用的引用地址,跨越调用未知代码.

在第二个示例中,编译器可以首先“看到”对象已被创建和销毁,其次,它是使用相同的值重新创建的.但该标准的作者希望允许编译器转换此代码

struct Foo {
    const int & x;
    Foo (int & i) : x(i) {}
};

int i = 1;
Foo f(i);

some_function_in_another_TU(&f);

std::cout << f.x;

进入这个:

struct Foo {
    const int & x;
    Foo (int & i) : x(i) {}
};

int i = 1;
Foo f(i);

some_function_in_another_TU(&f);

std::cout << i;           // this line is optimized

因为f的引用成员不能重新安置,因此仍然必须引用i. destruct-and-construct操作违反了引用成员x的非可重用性.

这种优化不应该引起特别的争议:考虑以下示例,使用const对象而不是具有const或引用成员的对象:

const int i = 1;
some_function_in_another_TU(&i);
std::cout << i;

这里我是一个编译时常量,some_function_in_another_TU无法有效地销毁它并在其位置创建另一个具有不同值的int.因此应该允许编译器为std :: cout<<发出代码1;这个想法是,对于其他类型的const对象和引用,类似应该是真的. 如果对未知代码调用可能会重置引用成员,或者更改const数据成员的值,那么语言的有用不变量(引用永远不会被重新定位,并且const对象永远不会更改它们的值)将被破坏.

猜你在找的C&C++相关文章