2016-08-03 8 views
2

Ich versuche, ein Tupel oder Paare des Index ein Parameterpaket zu erstellen. HierErstellen von Paaren von Index und Typ aus Parameterpack

ist ein Beispiel dafür, was der Code erreichen will:

{ 
    using Indices = 
     std::tuple< IndexTypePair< 0, int >, IndexTypePair< 1, int >, IndexTypePair< 2, float > >; 
    test2< Indices, 0 >(); 
    test2< Indices, 1 >(); 
    test2< Indices, 2 >(); 
    } 

Und hier ist die Verallgemeinerung:

{ 
    template < typename... T > 
    using make_index_tuple = tuple< IndexTypePair< Index_v< T, T... >, T >... >; 
    using Indices = make_index_tuple< int, int, float >; 
    test2< Indices, 0 >(); 
    test2< Indices, 1 >(); 
    test2< Indices, 2 >(); 
    } 

Diese Lösung auf die Antwort auf diese Frage basiert: How to get the index of a type in a variadic type pack?

Eines der Probleme, die ich habe, ist das Erstellen der Variadic Vorlage Alias, der vorherige Code gibt den folgenden Fehler:

$ make index-sequence clang++-3.8 -Wall -Werror -Wextra -std=c++14 
-pedantic -Wconversion -stdlib=libc++ -O3 -pthread index-sequence.cpp -o index-sequence index-sequence.cpp:50:5: error: expected expression 
    template < typename... T > 
    ^index-sequence.cpp:52:21: error: unknown type name 'make_index_tuple' 
    using Indices = make_index_tuple< int, int, float >; 
        ^... 

Hier sind einige andere Stücke diesen Code funktioniert:

#include <array> 
#include <cstddef> 
#include <iostream> 
#include <type_traits> 
#include <utility> 

template < typename T, typename... Ts > 
struct Index; 

template < typename T, typename... Ts > 
struct Index< T, T, Ts... > : std::integral_constant< std::size_t, 0 > 
{ 
}; 

template < typename T, typename U, typename... Ts > 
struct Index< T, U, Ts... > : std::integral_constant< std::size_t, 1 + Index< T, Ts... >::value > 
{ 
}; 

template < typename T, typename... Ts > 
constexpr std::size_t Index_v = Index< T, Ts... >::value; 

template < size_t i, typename T > 
struct IndexTypePair 
{ 
    static constexpr size_t index{i}; 
    using Type = T; 
}; 

template < typename Idx, size_t i > 
void test2() 
{ 
    using ITP = typename std::tuple_element< i, Idx >::type; 
    typename ITP::Type v{}; 
    //.... 
    std::cout << ITP::index << ' ' << v << std::endl; 
} 

Antwort

2

Verwenden Sie eine verschachtelte Struktur Setup, Ihnen zu helfen, zusammen mit dem Standard-make_index_sequence:

template < typename ... T > 
struct make_index_type_tuple_helper 
{  
    template< typename V > 
    struct idx; 

    template< size_t ... Indices > 
    struct idx<std::index_sequence<Indices...>> 
    { 
     using tuple_type = std::tuple<IndexTypePair<Indices, T>...>; 
    }; 

    using tuple_type = typename idx<std::make_index_sequence<sizeof...(T)>>::tuple_type; 
}; 

template < typename ... T> 
using make_index_type_tuple = typename make_index_type_tuple_helper<T...>::tuple_type; 

Dann können Sie es genau verwenden, wie Sie wollen (live demo):

using Indices = make_index_type_tuple< int, int, float >; 
test2< Indices, 0 >(); 
test2< Indices, 1 >(); 
test2< Indices, 2 >(); 
+0

Vielen Dank, es funktioniert super! Ich habe Ihren Helfer leicht geändert, um IndexTypePair als Vorlageparameter zu verwenden, das ist im Wesentlichen das, wonach ich gesucht habe. – XKpe