有界类型 的要求如下
variant
模板实例化时完成。(参见 boost::recursive_wrapper<T>
类型包装器,它接受不完整类型以启用递归 variant
类型。)作为 variant
的模板参数指定的每个类型必须至少满足上述要求。 此外,只有当 variant
的有界类型满足以下附加概念的要求时,某些 variant
的功能才可用
variant
本身才是 Assignable。(请注意,顶层 const
限定类型和引用类型 不 满足这些要求。)variant
本身才是 MoveAssignable。(请注意,顶层 const
限定类型和引用类型 不 满足这些要求。)T1
)满足概念的要求时,variant
本身才是 DefaultConstructible。variant
本身才是 EqualityComparable。variant
本身才是 LessThanComparable。variant
本身才是 OutputStreamable。variant
本身才是 Hashable。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)); }