次のコードはなぜ地球上で動作しますか?同じクラスのメンバーベクトルを宣言するにはどうすればよいですか?
struct A {
std::vector<A> subAs;
};
Aは不完全な型です、そうですか?もしA *のベクトルがあれば、私は理解するでしょう。しかし、ここで私はそれがどのように動作するのか分からない。これは再帰的な定義のようです。
次のコードはなぜ地球上で動作しますか?同じクラスのメンバーベクトルを宣言するにはどうすればよいですか?
struct A {
std::vector<A> subAs;
};
Aは不完全な型です、そうですか?もしA *のベクトルがあれば、私は理解するでしょう。しかし、ここで私はそれがどのように動作するのか分からない。これは再帰的な定義のようです。
paperinto C++17が採用されており、不完全なタイプを特定のSTLコンテナで使用することができます。それ以前は、未定義の動作でした。紙から引用する:イサクア会議の議論に基づいて
が、我々はアプローチを進める コンセンサス*を達成 - 「不完全 タイプのコンテナ」が、
std::vector
、std::list
に範囲を限定し、第1ステップとしてstd::forward_list
を使用します。
標準(強調鉱山)の変化と同様に:vector
をインスタンス化するとき
不完全型
T
は アロケータ満たすアロケータ-完全-要件場合に使用することができる (17.6.3.5.1)。 Tは、結果として得られる ベクターの特定のメンバーが参照される前に完了しなければならない。
std::vector<T, Allocator>
をインスタンス化する際にあなたの場所にデフォルトstd::allocator<T>
を残すのであれば、そこにあなたはそれを持って、それは常に紙によると、不完全型T
で動作します。それ以外の場合は、アロケータに不完全タイプT
でインスタンス化されているかどうかによって異なります。
Aは右、不完全タイプは?もしA *のベクトルがあれば、私は理解するでしょう。しかし、ここで私はそれがどのように動作するのか分からない。これは再帰的な定義のようです。
再帰はありません。非常に簡略化した形で、それに似て:
技術class A{
A* subAs;
};
、離れsize
、capacity
およびおそらくallocator
、std::vector
からのみ、そのアロケータを介して管理A
の動的配列へのポインタを保持する必要があります。 (そして、ポインタのサイズはコンパイル時に知られている。)
ので、実装は次のようになります。
namespace std{
template<typename T, typename Allocator = std::allocator<T>>
class vector{
....
std::size_t m_capacity;
std::size_t m_size;
Allocator m_allocator;
T* m_data;
};
}
私はhttp://stackoverflow.com/questions/6517231/ are-c-recursive-types-definitions-possible-in-can-i-put-a-vectortは更新する必要があります:) – kennytm
まあ、最低レベルで、これは「再帰的な定義」であるか否か'std :: vector'クラス自体に' A'型のサブオブジェクトが含まれているかどうかによって決まります。 'std :: vector'の典型的な実装では、' A'型の直接的なサブオブジェクトはありません。 'std :: vector'の典型的な実装では、制御されたシーケンスへのポインタを単に含んでいます。これにより、データの再帰が不要になり、不完全な型を引数として使用することが可能になります。ここでの唯一の質問は、言語仕様がそれを許すかどうかです。 – AnT
に関連する[不完全な型をベクターパラメータとしてテンプレートパラメータとして使用するにはどうすればよいですか?](http://stackoverflow.com/q/31345193/1708801) –