Boost.Variant 为我们提供了一个定义在 中的类: boost::variant 。 既然 boost::variant 是一个模板, 你必须要指定至少一个参数。 Variant 所存储的数据类型就由这些参数来指定。 上面的例子就给 v 指定了 double 类型和 char 类型。 注意, 一旦你将一个 int 值赋给了 v, 你的代码将不会编译通过。

    当然, 上面的例子也可以用一个 union 类型来实现, 但是与 union 不同的是: boost::variant 可以储存像 std::string 这样的 class 类型的数据。

    1. #include <boost/variant.hpp>
    2. #include <string>
    3.  
    4. int main()
    5. {
    6. boost::variant<double, char, std::string> v;
    7. v = 3.14;
    8. v = 'A';
    9. v = "Hello, world!";
    10. }

    要访问 v 中的数据, 你可以使用独立的 boost::get() 函数。

    所有 类型的值都可以被直接写入标准输入流这样的流中, 这可以在一定程度上让你避开运行时错误的风险。

    1. #include <boost/variant.hpp>
    2. #include <string>
    3. #include <iostream>
    4.  
    5. int main()
    6. boost::variant<double, char, std::string> v;
    7. v = 3.14;
    8. std::cout << v << std::endl;
    9. v = 'A';
    10. std::cout << v << std::endl;
    11. v = "Hello, world!";
    12. std::cout << v << std::endl;
    13. }

    想要分别处理各种不同类型的数据, Boost.Variant 为我们提供了一个名为 boost::apply_visitor() 的函数。

    boost::applyvisitor() 第一个参数需要传入一个继承自 boost::static_visitor 类型的对象。 这个类必须要重载 operator()() 运算符来处理 boost::variant 每个可能的类型。 相应的, 例子中的 _v 就重载了三次 operator() 来处理三种可能的类型: doublecharstd::string

    的第二个参数是一个 boost::variant 类型的值。

    在使用时, boost::apply_visitor() 会自动调用跟第二个参数匹配的 operator()() 。 示例程序中的 boost::apply_visitor() 就自动调用了三个不同的 operator 第一个是 double 类型的, 第二个是 char 最后一个是 std::string

    boost::apply_visitor() 的优点不只是“自动调用匹配的函数”这一点。 更有用的是, boost::apply_visitor() 会确认是否 boost::variant 中的每个可能值都定义了相应的函数。 如果你忘记重载了任何一个函数, 代码都不会编译通过。

    1. #include <boost/variant.hpp>
    2. #include <boost/any.hpp>
    3. #include <vector>
    4. #include <string>
    5. #include <iostream>
    6.  
    7. std::vector<boost::any> vector;
    8.  
    9. public boost::static_visitor<>
    10. {
    11. template <typename T>
    12. void operator()(T &t) const
    13. {
    14. vector.push_back(t);
    15. }
    16. };
    17.  
    18. int main()
    19. {
    20. boost::variant<double, char, std::string> v;
    21. v = 3.14;
    22. boost::apply_visitor(output(), v);
    23. v = 'A';
    24. boost::apply_visitor(output(), v);
    25. v = "Hello, world!";
    26. boost::apply_visitor(output(), v);

    既然 可以在编译期确定代码的正确性, 你就该更多的使用它而不是 boost::get()