Есть ли стандартный способ для меня выбрать тип в время компиляции по неподписанному индексу в c ++ 11?
Например, что-то вроде:
using type_0 = static_switch<0,T,U>; // yields type T
using type_1 = static_switch<1,T,U>; // yields type U
Если есть версия с вариационным шаблоном, это было бы очень полезно.
Это должно работать:
template<std::size_t N, typename... T>
using static_switch = typename std::tuple_element<N, std::tuple<T...> >::type;
Другой метод:
template<std::size_t N, typename T, typename... Ts>
struct static_switch {
using type = typename static_switch<N - 1, Ts...>::type;
};
template<typename T, typename... Ts>
struct static_switch<0, T, Ts...> {
using type = T;
};
Вы могли бы, вероятно, использовать boost::mpl::vector
хранить ваши типы и использовать boost::mpl::at<v,n>::type
чтобы получить тип из индекса.
template<std::size_t N, typename... T>
using static_switch = typename boost::mpl::at<boost::mpl::vector<T...>, N>::type;
Как насчет
template<size_t N, typename T, typename U>
struct static_switch {};
template<typename T, typename U>
struct static_switch<0, T, U>{typedef T type;};
template<typename T, typename U>
struct static_switch<1, T, U>{typedef U type;};
Вы бы использовали его следующим образом:
using type_0 = static_switch<0,T,U>::type; // yields type T
using type_1 = static_switch<1,T,U>::type; // yields type U
Это более или менее реализовано для вас в станд :: условно.
С C ++ 17 вы можете пойти и по-другому. Вместо явного вычисления типа вы можете использовать constexpr if
и делать разные вещи (в том числе возвращать разные типы) напрямую:
template<size_t N>
decltype(auto) foo(){
if constexpr(N%2==0){
return std::string("Hello I'm even");
}else{
return std::pair(
std::vector<char>{'O','d','d',' ','v','a','l','u','e'},
[](){ return N; });
}
}
foo<0>() // "Hello I'm even"foo<21>().second() // 21
Вы также можете использовать это, чтобы получить только тип:
using type_0 = decltype(foo<0>());
using type_1 = decltype(foo<1>());