我正在使用Boost Spirit中的Qi来解析VRML 1.0。有一个名为Separator的组节点,紧接在Separator下,可以保存许多不同类型的节点。 AST基于Boost.Variant,到目前为止看起来很冗长。我已接近达到变体中20种类型的限制。我知道我可以扩展变体的类型数量,但我确信必须有更好的方法来设计它。欢迎提示。
typedef boost::variant<
Nil,
Coordinate3,
Info,
Material,
MaterialBinding,
Normal,
NormalBinding,
Texture2,
Texture2Transform,
TextureCoordinate2,
ShapeHints,
MatrixTransform,
Rotation,
Scale,
Transform,
Translation,
boost::recursive_wrapper<Separator>
> VRML1Node;
答案 0 :(得分:3)
你确定你没有过早优化吗?根据我的经验,变体的“认知开销”不会随着变体 [1]
中元素类型的数量而增加。你可能想要
typedef mpl::vector< Coordinate3 > types_initial;
typedef mpl::push_front< types_initial, Nil >::type types;
boost::make_variant_over< types >::type VRML1Node;
在这种情况下,您可以使用动态多态性路径来代替静态多态性。
根据您的使用情况,性能不一定会受到严重影响。主要区别是
实际上可以改进存储要求(变体必须容纳最大的元素类型;当大多数元素类型实际上更小时,将有效地分配更少的内存)。
我不推荐它,但很明显你甚至可以使用boost::any
struct poorMansVariant
{
TypeCode discriminator; // TypeCode::Nil, TypeCode::Coordinate3...
boost::any value;
};
[1] 虽然当某些元素类型是可转换/可赋值时,情况可能会稍微复杂,或者通常,它们的构造函数变得模糊不清。但这是另一个话题