Подтвердить что ты не робот

Как переключать/выбирать типы во время компиляции?

Есть ли стандартный способ для меня выбрать тип время компиляции для индекса unsigned в С++ 11?

Например, что-то вроде:

using type_0 = static_switch<0,T,U>;  // yields type T
using type_1 = static_switch<1,T,U>;  // yields type U

Если существует версия с вариационным шаблоном, это было бы очень полезно.

4b9b3361

Ответ 1

Это должно работать:

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;
};

Ответ 2

Вероятно, вы можете использовать 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;

Ответ 3

Как насчет

 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

Это более или менее реализовано для вас в std:: условный.

Ответ 4

С С++ 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>());