2013-03-14 34 views
35

有沒有一種標準的方式讓我選擇編譯時在C++ 11中的無符號索引類型?在編譯期間如何切換/選擇類型?

例如,像:

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

如果有一個可變參數模板的版本,這將是非常有用的。

回答

42

這應該工作:

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

+1傑出答案。我一直對使用可變參數模板的新方法感興趣。謝謝你的另一個。 – WhozCraig 2013-03-14 08:16:21

+0

+1我不知道你可以有一個模板'使用'。 – 2013-03-14 08:24:44

+1

@AlexChamberlain並非所有的編譯器都支持它(它們是,它是它們的最新版本) – 2013-03-14 08:25:41

10

你也許可以使用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; 
8

如何

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::conditional你或多或少的實現。

+8

注意:如果只有兩種選擇,'std :: conditional'很好。由於OP正在討論索引,可能會有更多。 – 2013-03-14 08:23:21

1

隨着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>());