39 votes

Comment changer/sélectionner les types pendant la compilation ?

Existe-t-il un moyen standard de sélectionner un type à l'adresse suivante temps de compilation sur un index non signé en c++11 ?

Par exemple, quelque chose comme :

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

S'il existe une version variadic-template, elle serait très utile.

49voto

Pubby Points 29386

Cela devrait fonctionner :

template<std::size_t N, typename... T>
using static_switch = typename std::tuple_element<N, std::tuple<T...> >::type;

Une autre méthode :

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

10voto

Morwenn Points 4071

Vous pourriez probablement utiliser un boost::mpl::vector pour stocker vos types et utiliser boost::mpl::at<v,n>::type pour obtenir un type à partir de l'index.

template<std::size_t N, typename... T>
using static_switch = typename boost::mpl::at<boost::mpl::vector<T...>, N>::type;

9voto

Alex Chamberlain Points 2851

Et si

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

Vous l'utiliserez comme suit :

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

Ceci est plus ou moins implémenté pour vous dans std::conditionnel .

2voto

Johan Lundberg Points 5835

Avec C++17, vous pouvez également procéder d'une autre manière. Au lieu de calculer le type explicitement, vous pouvez utiliser constexpr if et faire différentes choses (y compris retourner différents types) directement :

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

Vous pouvez également l'utiliser pour obtenir uniquement le type :

using type_0 = decltype(foo<0>());
using type_1 = decltype(foo<1>());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X