3

次のコードは C++ で有効ですか?

template<typename T>
class Foo {
public:
    Foo(T& v) : v_(v) {}

private:
    T& v_;
};

int a = 10;
Foo<int> f(a);

void Bar(int& a) {
    new (&f)Foo<int>(a);
}

参照は 2 回バインドされるべきではありませんよね?

4

2 に答える 2

9

これは完全に無効です。

[basic.life]/1、強調鉱山:

タイプのオブジェクトの存続期間は、次の場合にT終了します。

  • T自明でないデストラクタ (12.4) を持つクラス型の場合、デストラクタの呼び出しが開始されます。
  • オブジェクトが占有するストレージは再利用または解放されます。

配置 new はストレージを再利用し、 で示されるオブジェクトの存続期間を終了しますf

[basic.life]/7:

オブジェクトの有効期間が終了した後、オブジェクトが占有していたストレージが再利用または解放される前に、元のオブジェクトが占有していたストレージの場所に新しいオブジェクトが作成された場合、元のオブジェクトを指すポインタ、その参照または、元のオブジェクトの名前が新しいオブジェクトを自動的に参照し、新しいオブジェクトの有効期間が開始されると、次の場合に新しいオブジェクトを操作するために使用できます。

  • 新しいオブジェクトのストレージは、元のオブジェクトが占めていたストレージの場所を正確にオーバーレイします。
  • 新しいオブジェクトが元のオブジェクトと同じ型である (最上位の cv 修飾子を無視する)、および
  • 元のオブジェクトの型が const 修飾されておらず、クラス型の場合、その型が const 修飾されているか参照型である非静的データ メンバーが含まれていない。
  • 元のオブジェクトは型の最派生オブジェクト (1.8) でTあり、新しいオブジェクトは型の最派生オブジェクトですT(つまり、基本クラスのサブオブジェクトではありません)。

Bar3 番目の箇条書きが満たされていないため、への呼び出し後、fは配置によって作成されたオブジェクトを参照しませんnewが、以前にそこに存在しなくなったオブジェクトを参照し、それを使用しようとすると未定義の動作が発生します。

CWG1776およびP0137R0も参照してください。

于 2015-11-04T06:30:52.737 に答える