Find a type in a parameter pack
c++, c++11
Solution
template <typename A, typename B, typename... C>
struct index_of
{
static constexpr int const value =
std::is_same<A, B>{}
? 0
: (index_of<A, C...>::value >= 0) ? 1+index_of<A, C...>::value : -1;
};
template <typename A, typename B>
struct index_of<A, B>
{
static constexpr int const value = std::is_same<A, B>{} -1;
};
Note the `std::is_same<A, B>{} -1` uses a conversion from `bool` to `int`.
Better by deriving from `integral_constant`:
template <typename A, typename B, typename... C>
struct index_of
: std::integral_constant
< int,
std::is_same<A, B>{}
? 0
: (index_of<A, C...>{} == -1 ? -1 : 1+index_of<A, C...>{})
>
{};
template <typename A, typename B>
struct index_of<A, B>
: std::integral_constant < int, std::is_same<A, B>{} -1 >
{};
If you don't need to return `-1` in case the type isn't found: (if anyone knows how to incorporate a `static_assert` here for a pretty diagnostic message, I'd appreciate a comment/edit)
template <typename A, typename B, typename... C>
struct index_of
: std::integral_constant < std::size_t,
std::is_same<A, B>{} ? 0 : 1+index_of<A, C...>{} >
{};
template <typename A, typename B>
struct index_of<A, B>
: std::integral_constant<std::size_t, 0>
{
constexpr operator std::size_t() const
{
return std::is_same<A, B>{}
? 0
: throw std::invalid_argument("Type not found!");
}
};
Problem
I'm trying to find type `A` in a parameter pack: ``` template <int I, typename A, typename B, typename ...C> struct index_of { static constexpr int const value = std::is_same<A, B>::value ? I : index_of<I + 1, A, C...>::value; }; template <int I, typename A, typename B> struct index_of<I, A, B> { static constexpr int const value = std::is_same<A, B>::value ? I : -1; }; ``` This seems to work, but I am unable to eliminate the nontype parameter `I`, which I would like to be a default parameter, but can't make it such, because of the parameter pack at the end. How to eliminate/hide `I`, so the metafunction becomes more user-friendly?