I've just started to use boost::variant and I've run into a situation where I'd like to ensure that a template parameter is only one of the types allowed in the variant. After reading the boost documentation it seems that a combination of static_assert, boost::variant::types and boost::mpl::contains should do exactly what I want. I've managed to get a solution working but it looks rather verbose and I wondered if there was a better way to do this. Anyway, my solution is:
typedef boost::variant<int, double, std::string> my_variant;
template<typename T>
void Func()
{
typedef boost::mpl::contains<my_variant::types, T>::type query_t;
typedef boost::mpl::bool_<true>::type query_result_t;
static_assert(boost::is_same<query_t, query_result_t>::value, "T isn't a valid my_variant type.");
// ...
}
Is it possible to get the same effect without boost::mpl::bool_ and/or boost::is_same?
You can get rid of is_same
and query_result_t
, since contains
returns an MPL Integral Constant:
typedef boost::variant<int, double, std::string> my_variant;
template<typename T>
void Func()
{
static_assert(boost::mpl::contains<my_variant::types, T>::type::value, "T isn't a valid my_variant type.");
// ...
}
I believe that's as concise as it gets - you need some predicate to query the type sequence, and boost::mpl::contains
is the correct one for that.