15

このコード:

class Foo {
    std::unordered_map<std::string, Foo> x;
};

エラーが発生します:

/usr/include/c++/4.7/bits/stl_pair.h:94:11:
  error: 'std::pair<_T1, _T2>::second' has incomplete type
foo.cpp:4:7: error: forward declaration of 'class Foo'

ただし、このコードは問題なくコンパイルされます。

class Foo {
    std::vector<Foo> x;
};

これはライブラリ/コンパイラのバグですか?

4

1 に答える 1

21

C ++標準では、さまざまなスマートポインターに対して、テンプレートパラメーターを不完全な型にすることが許可されていると指定されています。

2017以降のバージョンの標準ではvalue_type、コンテナテンプレート、、、およびのクラステンプレートをインスタンス化するときに、アロケータタイプが「アロケータの完全性要件」を満たしている場合にのみ、コンテナを不完全なタイプにするstd::forward_listことstd::liststd::vectorできます。デフォルトのアロケータテンプレートstd::allocatorは、常にアロケータの完全性要件を満たしています。コンテナクラステンプレートのメンバーをインスタンス化するには、value_typeが完了する必要があります。

その他の標準コンテナタイプの場合、この情報は提供されません。指定されていない場合、実装は、あるコンテナクラステンプレートに対して不完全な型を受け入れ、別のテンプレートに対しては受け入れず、それでも準拠することができます。

コードを移植可能にするために、標準で特に許可されている場合を除いて、タイプが完成する前に任意のタイプのコンテナーを作成することは避けてください。

正式には、一般的な制約は、コードに適用される次のルール( [res.on.functions] )にあります。

場合によっては(置換関数、ハンドラー関数、標準ライブラリテンプレートコンポーネントのインスタンス化に使用される型の操作)、C++標準ライブラリはC++プログラムによって提供されるコンポーネントに依存します。これらのコンポーネントが要件を満たしていない場合、標準では実装に要件はありません。

特に、次の場合の影響は定義されていません。

..。

  • テンプレートコンポーネントをインスタンス化するときに不完全な型がテンプレート引数として使用されている場合。ただし、そのコンポーネントで特に許可されている場合を除きます。

forward_list、、listおよびの不完全なテンプレート引数を具体的に許可する3つのステートメントvectorは、セクション[forwardlist.overview][list.overview]、および[vector.overview]にあります。

于 2012-10-26T15:14:38.850 に答える