Boost C++ 库

...世界上最受尊敬和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

PrevUpHomeNext

参考

概念
头文件 <boost/variant.hpp>
头文件 <boost/variant/variant_fwd.hpp>
头文件 <boost/variant/variant.hpp>
头文件 <boost/variant/recursive_variant.hpp>
头文件 <boost/variant/recursive_wrapper.hpp>
头文件 <boost/variant/apply_visitor.hpp>
头文件 <boost/variant/multivisitors.hpp>
头文件 <boost/variant/get.hpp>
头文件 <boost/variant/polymorphic_get.hpp>
头文件 <boost/variant/bad_visit.hpp>
头文件 <boost/variant/static_visitor.hpp>
头文件 <boost/variant/visitor_ptr.hpp>

概念

BoundedType

有界类型 的要求如下

  • CopyConstructible 或 MoveConstructible。
  • 析构函数维护不抛出异常安全保证。
  • variant 模板实例化时完成。(参见 boost::recursive_wrapper<T> 类型包装器,它接受不完整类型以启用递归 variant 类型。)

作为 variant 的模板参数指定的每个类型必须至少满足上述要求。 此外,只有当 variant 的有界类型满足以下附加概念的要求时,某些 variant 的功能才可用

  • Assignable:当且仅当其每个有界类型都满足概念的要求时,variant 本身才是 Assignable。(请注意,顶层 const 限定类型和引用类型 满足这些要求。)
  • MoveAssignable:当且仅当其每个有界类型都满足概念的要求时,variant 本身才是 MoveAssignable。(请注意,顶层 const 限定类型和引用类型 满足这些要求。)
  • DefaultConstructible [20.1.4]:当且仅当其第一个有界类型(即,T1)满足概念的要求时,variant 本身才是 DefaultConstructible
  • EqualityComparable:当且仅当其每个有界类型都满足概念的要求时,variant 本身才是 EqualityComparable
  • LessThanComparable:当且仅当其每个有界类型都满足概念的要求时,variant 本身才是 LessThanComparable
  • OutputStreamable:当且仅当其每个有界类型都满足概念的要求时,variant 本身才是 OutputStreamable
  • Hashable:当且仅当其每个有界类型都满足概念的要求时,variant 本身才是 Hashable

StaticVisitor

T 类型的 静态访问器 的要求如下

  • 必须允许通过重载 operator() 作为函数调用,明确接受 T 类型的任何值。
  • 必须公开内部类型 result_type。 C++14 兼容的编译器可以自动检测 result_type,但如果定义了 result_type,则会坚持使用它。(有关使用函数作为访问器的解决方案,请参阅 boost::visitor_ptr。)
  • 如果 result_type 不是 void,则函数对象的每个操作都必须返回一个隐式转换为 result_type 的值。
示例

以下类满足几种类型的静态访问器的要求(即,显式地:intstd::string;或者,例如,隐式地:shortconst char *;等等)

class my_visitor
    : public boost::static_visitor<int>
{
public:

    int operator()(int i)
    {
        return i * 2;
    }

    int operator()(const std::string& s)
    {
        return s.length();
    }

};

另一个示例是以下类,其函数调用运算符是成员模板,允许它对多种类型的值进行操作。 因此,以下类是任何支持流输出的类型(例如,intdoublestd::string 等)的访问器

class printer
    : public boost::static_visitor<>
{
    template <typename T>
    void operator()(const T& t)
    {
        std::cout << t << std::endl;
    }
};

C++14 兼容的编译器自动检测 result_type

    boost::variant<int, float> v;
    // ...

    boost::apply_visitor(
        [](auto val) { return std::to_string(val); },
        v
    );

OutputStreamable

可输出流化 类型 T 的要求如下

  • 对于类型为 T 的任何对象 tstd::cout << t 必须是有效的表达式。

Hashable

可哈希化 类型 T 的要求如下

  • 对于类型为 T 的任何对象 tboost::hash<T>()(t) 必须是有效的表达式。

头文件 <boost/variant.hpp>

此头文件仅作为用户的便利而存在,包括 boost/variant 目录中的所有头文件,除了 <boost/multivisiors.hpp>。

提供 boost::variantboost::make_variant_overboost::make_recursive_variantboost::make_recursive_variant_over 类模板以及 boost::recursive_variant_ 标记类型的前向声明。 还定义了几个预处理器符号,如下所述。

BOOST_VARIANT_ENUM_PARAMS(param)
BOOST_VARIANT_ENUM_SHIFTED_PARAMS(param)
BOOST_VARIANT_DO_NOT_SPECIALIZE_STD_HASH
BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
namespace boost {
  template<typename T1, typename T2 = unspecified, ..., 
           typename TN = unspecified> 
    class variant;

  template<typename Sequence> class make_variant_over;
  template<typename T1, typename T2, ..., typename TN> 
    void swap(variant<T1, T2, ..., TN> &, variant<T1, T2, ..., TN> &);
  template<typename ElemType, typename Traits, typename T1, typename T2, ..., 
           typename TN> 
    std::basic_ostream<ElemType,Traits> & 
    operator<<(std::basic_ostream<ElemType,Traits> &, 
               const variant<T1, T2, ..., TN> &);
  template<typename T1, typename T2, ..., typename TN> 
    std::size_t hash_value(const variant<T1, T2, ..., TN> &);
}
namespace boost {
  typedef unspecified recursive_variant_;

  template<typename T1, typename T2 = unspecified, ..., 
           typename TN = unspecified> 
    class make_recursive_variant;
  template<typename Sequence> class make_recursive_variant_over;
}
namespace boost {
  template<typename T> class recursive_wrapper;
  template<typename T> class is_recursive_wrapper;
  template<typename T> class unwrap_recursive_wrapper;
}
namespace boost {
  template<typename Visitor> class apply_visitor_delayed_t;
  template<typename Visitor> class apply_visitor_delayed_cpp14_t;
  template<typename Visitor, typename Variant> 
    typename Visitor::result_type apply_visitor(Visitor &, Variant&&);
  template<typename Visitor, typename Variant> 
    typename Visitor::result_type apply_visitor(const Visitor &, Variant&&);
  template<typename BinaryVisitor, typename Variant1, typename Variant2> 
    typename BinaryVisitor::result_type OR decltype(auto) 
    apply_visitor(BinaryVisitor &, Variant1&&, Variant2&&);
  template<typename BinaryVisitor, typename Variant1, typename Variant2> 
    typename BinaryVisitor::result_type OR decltype(auto) 
    apply_visitor(const BinaryVisitor &, Variant1&&, Variant2&&);
  template<typename MultiVisitor, typename Variant1, typename Variant2, 
           typename Variant3> 
    typename MultiVisitor::result_type OR decltype(auto) 
    apply_visitor(MultiVisitor &, Variant1&&, Variant2&&, Variant3&&, ...);
  template<typename MultiVisitor, typename Variant1, typename Variant2, 
           typename Variant3> 
    typename MultiVisitor::result_type OR decltype(auto) 
    apply_visitor(const MultiVisitor &, Variant1&&, Variant2&&, Variant3&&, 
                  ...);
  template<typename Visitor> 
    apply_visitor_delayed_t<Visitor> apply_visitor(Visitor &);
  template<typename Visitor> 
    apply_visitor_delayed_cpp14_t<Visitor> apply_visitor(Visitor &);
}

提供用于三个或更多 variant 参数的 apply_visitor 的声明。

namespace boost {
  template<typename MultiVisitor, typename Variant1, typename Variant2, 
           typename Variant3> 
    typename MultiVisitor::result_type OR decltype(auto) 
    apply_visitor /*three or more variant parameters*/(MultiVisitor &, 
                                                       Variant1&&, 
                                                       Variant2&&, 
                                                       Variant3&&, ...);
  template<typename MultiVisitor, typename Variant1, typename Variant2, 
           typename Variant3> 
    typename MultiVisitor::result_type OR decltype(auto) 
    apply_visitor /*three or more variant parameters*/(const MultiVisitor &, 
                                                       Variant1&&, 
                                                       Variant2&&, 
                                                       Variant3&&, ...);
}
namespace boost {
  class bad_get;
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U * relaxed_get(variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U * relaxed_get(const variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U & relaxed_get(variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U & relaxed_get(const variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U && relaxed_get(variant<T1, T2, ..., TN> &&);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U * strict_get(variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U * strict_get(const variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U & strict_get(variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U & strict_get(const variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U && strict_get(variant<T1, T2, ..., TN> &&);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U * get(variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U * get(const variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U & get(variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U & get(const variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U && get(variant<T1, T2, ..., TN> &&);
}
namespace boost {
  class bad_polymorphic_get;
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U * polymorphic_relaxed_get(variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U * polymorphic_relaxed_get(const variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U & polymorphic_relaxed_get(variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U & polymorphic_relaxed_get(const variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U * polymorphic_strict_get(variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U * polymorphic_strict_get(const variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U & polymorphic_strict_get(variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U & polymorphic_strict_get(const variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U * polymorphic_get(variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U * polymorphic_get(const variant<T1, T2, ..., TN> *);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    U & polymorphic_get(variant<T1, T2, ..., TN> &);
  template<typename U, typename T1, typename T2, ..., typename TN> 
    const U & polymorphic_get(const variant<T1, T2, ..., TN> &);
}
namespace boost {
  class bad_visit;
}
namespace boost {
  template<typename ResultType> class static_visitor;
}
namespace boost {
  template<typename T, typename R> class visitor_ptr_t;
  template<typename R, typename T> visitor_ptr_t<T,R> visitor_ptr(R (*)(T));
}

PrevUpHomeNext