对有界类型的要求如下
variant
模板实例化时必须是完整的。(参见 boost::recursive_wrapper<T>
,它是一个接受不完整类型的类型包装器,用于启用递归 variant
类型。)指定为 variant
模板参数的每个类型都必须至少满足上述要求。此外,variant
的某些特性只有在其有界类型满足以下附加概念的要求时才可用
variant
本身才可赋值。(注意,顶级 const
限定类型和引用类型不满足这些要求。)variant
本身才可移动赋值。(注意,顶级 const
限定类型和引用类型不满足这些要求。)T1
)满足该概念的要求时,variant
本身才可默认构造。variant
本身才可相等比较。variant
本身才可小于比较。variant
本身才可输出流。variant
本身才可哈希。对类型 T
的静态访问者的要求如下
operator()
允许作为函数调用,并且能够明确地接受任何 T
类型的值。result_type
。兼容 C++14 的编译器可以自动检测 result_type
,但如果定义了 result_type
,则将继续使用它。(有关将函数用作访问者的解决方案,请参见 boost::visitor_ptr
。)result_type
不是 void
,则函数对象的每个操作都必须返回一个可隐式转换为 result_type
的值。以下类满足多种类型的静态访问者的要求(即,显式:int
和 std::string
;或者,例如,隐式:short
和 const 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();
}
};
另一个示例是以下类,其函数调用运算符是一个成员模板,允许它对多种类型的值进行操作。因此,以下类是任何支持流输出的类型的访问者(例如,int
、double
、std::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 );
提供 boost::variant
、boost::make_variant_over
、boost::make_recursive_variant
和 boost::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)); }