I use a lot of std::variant
s. I have this trusty helper concept that matches alternatives of a specific variant type:
template<typename alternative_type, typename variant_type>
struct alternative_c_impl {
static_assert(false, "can t use is_alternative<> with a non-variant"); // legal in C++23
};
template<typename alternative_type, typename... variant_alternatives>
struct alternative_c_impl<alternative_type, std::variant<variant_alternatives...>>
: std::disjunction<std::is_same<alternative_type, variant_alternatives>...>
{};
template<typename alternative_type, typename variant_type>
concept alternative_c = alternative_c_impl<alternative_type, variant_type>::value;
auto main() -> int
{
using simple_variant = std::variant<int, float>;
static_assert(alternative_c<int, simple_variant>);
static_assert(alternative_c<std::string, simple_variant> == false);
}
However in C++23, we can now have types derived from std::variant
. For such, this approach fails expectedly with the initial static_assert
. My template skills got a little rusty and I m having trouble expanding this to work with such a type. I guess it somehow involves std::derived_from
. Speaking in code, I want a mystery_c
concept that works analogously:
struct derived_var : std::variant<int, float>
{
};
auto main() -> int
{
static_assert(mystery_c<int, derived_var>);
static_assert(mystery_c<std::string, derived_var> == false);
}