Вы в основном хотите QVariant
без остальной части Qt, тогда:)?
Как уже упоминали другие, вы можете использовать std::variant
и поместить using MyVariant = std::variant<t1, t2, ...>
в некоторый общий заголовок, а затем использовать его везде, где это требуется. Это не так уж и элегантно, как вы можете подумать - определенные типы c, которые нужно передать, предоставляются только в одном месте. Это единственный способ сделать это без создания механизма метатипа, который может инкапсулировать операции с любым типом объекта.
Вот где приходит boost::any
: он делает именно это. Он оборачивает понятия и, таким образом, поддерживает любой объект, который реализует эти понятия. Какие концепции требуются, зависит от вас, но в целом вы должны выбрать достаточное их количество, чтобы сделать тип пригодным для использования и полезным, но не слишком много, чтобы преждевременно исключить некоторые типы. Вероятно, это путь к go, у вас будет: using MyVariant = any<construct, _a>;
затем (где construct
- список контрактов, пример которого приведен в качестве примера в документации и _a
является заполнителем типа из boost::type_erasure
.
Принципиальное различие между std::variant
и boost::any
заключается в том, что variant
параметризован для конкретных типов , тогда как Параметр any
параметризован для контрактов, с которыми связаны типы . Затем любой из них с радостью сохранит произвольный тип, который выполняет все эти контракты. "Центральное расположение", в котором вы определяете псевдоним для варианта типа будет постоянно расти с variant
, так как вам нужно инкапсулировать больше типов. С any
центральное расположение будет в основном stati c и будет меняться редко, так как изменение требований контракта, вероятно, потребует исправлений / адаптации к перевозимые типы, а также точки использования.