ソリューション1 - ラッパークラスを使用して:私は利用可能std::variant
を持っていないので、
struct node {
using myvar = boost::variant< unsigned, boost::recursive_wrapper<node> >;
using childmap = std::unordered_map< std::string, myvar >;
node() {}
node(std::initializer_list<childmap::value_type> il) :
children(il) {}
childmap children;
};
は、私がここにブースト::バリアントを使用しています。 boost::variant
には通常完全なタイプが必要ですが、この時点ではnode
はまだ不完全であるため、boost::recursive_wrapper
が必要です。
boost::recursive_wrapper
は何も魔法です。それはポインタの周りのラッパーです!わかっているように、問題のない不完全な型のポインタを宣言することができます。このラッパークラスは、割り当て、解放、値セマンティクスの世話をすることによってポインタが使用されるという事実を隠すだけです。 boost::variant
によって特別なサポートが提供され、ラッパーを完全に透過的にするので、ラッパークラスがまったくないかのようにバリアントを使用することができます。
使用法:バリアントのコンストラクタは、ネストされた初期化子リストから種類を推測することはできませんので
node n {
{ "foo", 1 },
{ "bar", 2 },
{ "baz", node {
{ "bim", 3 },
{ "bam", 4 }}
}
};
n.children[ "fum" ] = 5;
n.children[ "fup" ] = node{{ "fap", 6 }};
初期化子リストで明示的に「ノード」が必要です。
デモ:http://coliru.stacked-crooked.com/a/123c59a3523c39ed
ソリューション2 - unordered_map由来:
これは、 "子供" メンバーの必要性を取り除きます。
struct nodemap :
std::unordered_map<
std::string,
boost::variant< unsigned, boost::recursive_wrapper<nodemap> > >
{
using base = std::unordered_map<
std::string,
boost::variant< unsigned, boost::recursive_wrapper<nodemap> > >;
// Forward all constructors of the base class.
using base::base;
};
使用法:
nodemap n{
{ "foo", 1 },
{ "bar", 2 },
{ "baz", nodemap{
{ "bim", 3 },
{ "bam", 4 }}
}};
n[ "fum" ] = 5;
n[ "fup" ] = nodemap{{ "fap", 6 }};
詳しい使用例:
// Add something to a child nodemap.
boost::get<nodemap>(n[ "baz" ])[ "fap" ] = 7;
// This will throw a boost::bad_get exception because n[ "foo" ] is not a nodemap.
//boost::get<nodemap>(n[ "foo" ])[ "fap" ] = 8;
// To avoid this problem, we can check if the child actually is a nodemap:
if(nodemap* pn = boost::get<nodemap>(&n[ "foo" ]))
{
(*pn)[ "fap" ] = 8;
}
デモ:http://coliru.stacked-crooked.com/a/69914ec5646129f2
あなたは木のツリーを必要としますか?たとえば、すべてのデータに対して1つのツリーを使用し、2つの「別々の」ツリー間の「パーティション」であるかどうかを示すために、各ノードに追加された追加情報を使用できます。 –
@JohnZwinck私は本当に木の木を必要としません。木の木は純粋な木構造で自然です。私が純粋なノードベースのツリー構造を使用するならば、それはより簡単になります。主に性能問題のためにunordered_mapを選択し、ツリーを平坦化しました。しかし、これをしても実際にはより良いパフォーマンスが得られないかもしれないことを示唆しています。 – YiFei
余分な '{}'はどうですか? – Yakk