2011-11-30 4 views
16

時にはそれが再帰構造を得るために、不完全な型を持つ標準コンテナをインスタンス化すると便利です:標準のコンテナテンプレートを不完全な型でインスタンス化できますか?

struct multi_tree_node { // Does work in most implementations 
    std::vector<multi_tree_node> child; 
}; 

struct trie_node { // Does not work in most implementations 
    std::map< char, trie_node > next; 
}; 

これは、コンテナがいずれかを渡すか、または戻り値の型value_typeまたはメンバ関数のメンバーを持っていないので、動作する傾向があるvalue_typeオブジェクトを値で表します。スタンダードは不完全なテンプレート引数についてはあまり言わないようですが、C++ 11§17.6.4.8[lib.res.on.functions]、「他の関数の要件」の下に1ビットがあります:

特に、以下の場合、効果は未定義です。テンプレートコンポーネントをインスタンス化する際にテンプレート引数として不完全な型(3.9)が使用されている場合(そのコンポーネントに対して特に許可されていない場合)

インスタンス化がブロックスコープ内にないにもかかわらず、これにより上記の構文が不正になりますか?これは「標準ライブラリテンプレートコンポーネントをインスタンス化するために使用される型の操作」(17.6.4.8も参照)にありますか?または、特に必要なインスタンス化がすべて成功した場合に、不完全な型に対して失敗する可能性のあるテンプレートのインスタンス化を禁止するライブラリ実装ですか?

編集:だけ呼び出し、制限、その他の機能をインスタンス化「タイプの操作を...」ブロックスコープのものにすることができる機能は、署名と部材の内容より厳しい要件にメンバ関数の内容を保持するように思われるためクラス定義。結局のところ、タイプが完了するまでmulti_tree_nodeとすることは間違いありません。これは、ブロックスコープで使用されていても、不完全な型引数であるを明示的にサポートするstd::unique_ptrにも及んでいます。

編集2:trie_nodeの例をテストすることを迷惑にならないように私に奉仕します。 @Iseリンクされたthe articleの破損の例と同じです。しかし、記事は "それがうまくいかない"ということを当然のように思っているようだが、解決策は私にとっては単純だと思われる - std::mapの内部tree_nodeクラスはメンバ非テンプレートクラスではなく非メンバテンプレートでなければならない。

とにかく、その記事はデザインの意図をかなりよく確立しているので、「機能に関する要件」の副題になっているというニットピックはちょうどそのことです。任意の具体的な実装は、このような構成をサポートしている問題がない場合でも、

標準は、単にあなたがこれを行う必要がありません言う:

+1

投稿したコードに不完全な型はありませんか? –

+1

@JohnDibling: 'trie_node'は' next'を定義するときに不完全です。 –

+1

@ JohnDiblingクラスのスコープ内では、不完全です。 – Potatoswatter

答えて

4

は個人的に、私は17.6.4.8/2に文言をインスタンス感じが曖昧少し ですが、 this articleによると、 標準の意図は 標準コンテナを使用して再帰的なデータ型を許可していないようです。関連ノートで

それは class C { std::vector<C> x; };をコンパイルしながら、VC2005は、 class C { std::deque<C> x; };のためのエラーを発行...
はしかし、私の理解では、この制限は、単に標準コンテナの実装の 自由を拡大するためです。 Kerrek SBが述べたように だから、 再帰的なデータ構造を許可するコンテナがあることができ、かつ Boost.Container は、この機能を提供しているようです。

10

はここでの解釈で私の試みです。しかし、例えばベクトルが常に5つの要素のためのスペースを含む「小さなベクトル」の最適化を書こうとしているとします。あなたは自己参照型なのですぐに問題になるでしょう。これは、たとえベクトルが値型のサイズに応じてある種の静的分岐を採用していても問題になります。

したがって、このような構造を実装から除外しないために、標準では単に完全な型のみを使用する必要があると述べています。言い換えれば、ほとんどのコンテナに値型への参照またはポインタしか含まれていないという事実は、標準の要件ではなく実装の詳細です。あなたがあなた自身のクラステンプレートを定義した場合、明示的に不完全なタイプをサポートしていますようにそれを設計することは完全に可能である:。ただ、これを明確にする

標準からの例はstd::unique_ptrです。これは不完全型パラメータT[](またはさらにはvoid)で完全に満足しています。

+0

+1素晴らしい例ですが、私はいくつかの標準的な標準の解釈を待つつもりです...私のコードは、引用された要件に確かに違反しますが、問題のもう一つの部分は、要件が関数/ブロックスコープ外に適用されるかどうかです。 (関数だけが他の関数を呼び出してインスタンス化する可能性があるため、メンバ関数の内容をシグネチャやメンバクラス定義の内容とは異なる標準に保つように見えます) – Potatoswatter

+0

"小さなベクトル"はあまり良い例ではありません。その最適化は標準によって許可されていません。 –

関連する問題