Я использую Qi от Boost Spirit для разбора VRML 1.0. Существует групповой узел с именем Разделитель, и непосредственно под Разделителем можно хранить множество различных типов узлов. 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;
Вы уверены, что не оптимизируете преждевременно?? По моему опыту «когнитивные накладные расходы» варианта не увеличиваются с увеличением количества типов элементов в варианте.[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] хотя ситуация может немного усложняться, когда некоторые типы элементов являются конвертируемыми / присваиваемыми, или в целом их конструкторы становятся неоднозначными. Но это другая тема
Других решений пока нет …