动态扩展 boost::variant 的类型

Extending types of a boost::variant dynamically

本文关键字:类型 variant 动态 boost 扩展      更新时间:2023-10-16

>我必须编写一个将数据导出为各种格式的库。每种格式都是给定boost::variant的一种类型,例如

typdef boost::variant<csv, xml, hdf5> TFormat

格式为 csv、xml 和 hdf5。这种方法对我来说效果很好。该库应该非常通用,并且对客户端的可能扩展开放。因此,如果客户端能够以统一的方式添加用户定义的格式,那就太好了。

我希望 I 客户端可以添加几个宏,例如

REGISTER_FORMAT(binary)
REGISTER_FORMAT(mpeg)

之后我的typedef神奇地变成了

typedef boost::variant<csv, xml, hdf, binary> TFormat.

我已经想出了如何使用以下 mpl 代码构造类型动态boost::variant,幸运的是可以使用 MSVC2010 进行编译。

#include <boost/variant/variant.hpp>
#include <boost/mpl/vector.hpp>
int main() {
    // Adding the type int, to a vector containing the types double and std::string
    using namespace boost;
    typedef mpl::vector< double, std::string > DefaultTypes;
    typedef mpl::push_front< DefaultTypes, int >::type ExtendedTypes;
    // typedef TFormat of type boost::variant<double, std::string, int>
    typedef boost::make_variant_over< ExtendedTypes >::type TFormat;
    return 0;
}

我仍然无法实现上述宏,因为事先不清楚客户端调用REGISTER_FORMAT的频率,或者他是否会使用该宏。

有没有人知道如何实现这样的宏或类似的东西?

我希望 I 客户端可以添加几个宏,例如

这是不可能的。C 预处理器没有"堆栈",没有"变量",没有"状态"。您拥有的唯一状态是在当前所在的扩展中。您不能"保存内容以备后用",甚至不能分配任何东西。上一个宏不可能影响下一个宏。

或类似的东西?

您可以使用不同的预处理器,例如 M4,但是如果宏调用跨越多个文件集成它可能非常困难。

如前所述,您可以使用有状态模板技巧来累积类型。