2012-03-25 11 views
11

は、私はこのような再帰的なデータ型を持っています。どこかでエラーを出していますか?これは標準の一部ですか?テンプレートの再帰的なデータ型

テンプレートパラメータ(std::stackstd::queueなど)で内部コンテナを決定したいと思っていますが、SomeTypeが既に定義されている必要があるため、これを行う方法はわかりません。

不完全な例:

template<typename T, typename C = std::map<T, SomeType<[???]>>> 
struct SomeType { 
    C mapping; 
}; 

SomeType<int, [???]> foo; 

私は、これは、ランタイム間接に行うことができます知っているが、それは私が探しているものではないのです。

+1

標準ライブラリコンテナテンプレートは、あなたが完全な種類とそれらをインスタンス化することが必要です。それ以外は未定義の動作です。あなたはそれで生きなければなりません。あなたはそれを回避するために、ピンプルソリューションを使用することができます。 –

+0

@KerrekSBそうですか?私は定期的にノードが 'std :: vector children'の観点から実装されたn-aryツリーを作成しました。 –

+0

@ KonradRudolph:インスタンス化時に型が完全であることを確認する必要があります。それは微妙な問題かもしれません。 –

答えて

7

あなたのクラスは定義の最後の}の前にどこかで不完全です。そのため、mappingメンバーは型のテンプレート引数に不完全型SomeTypeを使用しています。

The standard does not allow this, and it is pure luck that it works with some STL containers.

あなたの第二の質問は同じ答えに該当する - 最初の場所でそれを行うことは違法です。

+0

Hmm。残念ながら、私は、不完全な型の 'std :: map 'が原則どおりに機能しないのかという記事の議論を理解していません。これは、 'std :: vector >'のようなものではありませんか?( 'std :: pair 'は不完全ですか?他のコンテナについても同じです。 –

+0

これは説明が必要な場合は、私はチャットルームを開くことをお勧めします。それは難しくない、ちょうどコメントセクションには適していない...今、私は明示的にこれについてのチャットルームを開きます... – Irfy

+1

ここでチャットしましょう:http: /chat.stackoverflow.com/rooms/9282/stl-with-incomplete-types – Irfy

4

明白な理由から、再帰的なデフォルトパラメータでテンプレートを定義することはできません。不完全な型の標準ライブラリコンテナテンプレートをインスタンス化することはできません。標準ではそうだと言います(そうでなければ未定義の動作です)。しかし、通常のPIMPLイディオムが役に立ちます:

#include <map> 
#include <memory> 
template <typename T> class SomeType 
{ 
    typedef std::map<T, SomeType<T>> map_type; 
    typedef std::unique_ptr<map_type> map_ptr; 
    map_ptr pimpl; 
public: 
    SomeType() : pimpl(new map_type) { } 
}; 
+1

boost :: containerライブラリは、不完全な型の再帰的なコンテナを可能にするほとんどのSTL型の代替案を提供します。それは現在、unordered_map – mark

+0

@マークを提供していません:ありがとう、それは知って良いです! –

3

コンテナに不完全な型を使用することはできませんが、スマートポインタで行うことができます。 そして、あなたは未定義の型パラメータを持つテンプレートの種類を作成することはできませんが、あなたはここにいくつかのトリックを使用することができます。

template<typename T, template <typename U, typename V, typename... Args> class Container = std::unordered_map > 
struct SomeType { 
    Container<T, std::unique_ptr<SomeType> > mapping; 
}; 
+0

コンテナのデフォルト値がstd :: vectorになるように最初の行を変更することはできますか? –

+0

@NielsLohmann、技術的に 'template class Container = std :: vector>'と書くことができますが、 'std :: unordered_map'とは矛盾します。 mapは_assosiative_ conrtainerなので、vectorは単なる配列です。 – Lol4t0

関連する問題