2013-03-14 4 views
35

Gibt es einen Standard Weg für mich, einen Typ unter Kompilierzeit auf einem vorzeichenlosen Index in C++ 11 auszuwählen?Wie wechsle ich während der Kompilierzeit Typen?

Zum Beispiel so etwas wie:

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

Wenn es eine variadische-Template-Version ist, wäre es sehr nützlich sein.

Antwort

42

sollte diese Arbeit:

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

Eine andere Methode:

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 Outstanding Antwort . Ich bin immer an neuen Möglichkeiten interessiert, variadische Vorlagen zu verwenden. Danke für ein anderes. – WhozCraig

+0

+1 Ich wusste nicht, dass Sie eine Templates-Verwendung haben könnten. –

+1

@AlexChamberlain nicht alle Compiler unterstützen es (es tun sie, es ist ihre neueste Version) –

10

Sie wahrscheinlich eine boost::mpl::vector speichern Sie Ihre Art und Nutzung von boost::mpl::at<v,n>::type eine Art zu bekommen mit aus dem Index nutzen könnten.

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

Wie wäre es

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

Sie würden es wie folgt verwenden:

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

Dies ist mehr oder weniger in std::conditional für Sie umgesetzt.

+8

Hinweis: 'std :: conditional' ist großartig, wenn es nur 2 Alternativen gibt. Da das OP von einem Index spricht, könnte es mehr geben. –

1

Mit C++ 17 können Sie auch einen anderen Weg gehen. Statt die Art der Berechnung explizit können Sie constexpr if verwenden und verschiedene Dinge tun (einschließlich der Rückkehr verschiedene Typen) direkt:

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 

Sie auch dies nur die Art erhalten verwenden können:

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