2014-06-11 10 views
6

Próbuję zamienić dwa parametry o zmiennej liczbie argumentów szablonu w czasie kompilacji:Jak zamienić dwa parametry szablonu variadic w czasie kompilacji?

template<int...Numbers>struct sequence{}; 

template<size_t first,size_t second> 
struct Swap_Pair 
{ 
    const static size_t First = first; 
    const static size_t Second = second; 
}; 

template <int...Numbers,class swap_pair> 
struct Swap_Data 
{ 
    static std::array<int, sizeof...(Numbers)> data_;//How to swap Numbers base on the pair and store it in data_ ? 
}; 

Sprawa stosowanie powinno być:

sequence<1, 2, 3, 4, 5, 6> array; 
auto result = Swap_Data < array, Swap_Pair<2, 5> > ::data_; 
//result is now std::array which contains 1 2 6 4 5 3 

nie mogę dowiedzieć się, jaka jest właściwa sposób pisania Swap_Data.

Jak mogę utworzyć zamianę cykliczną do zamiany parametrów variadic i konwersji na std :: array w czasie kompilacji?

+0

sprawdzić ten https://github.com/Manu343726/Turbo/blob/reboot/bind.hpp – Manu343726

+0

coś takiego jak 'int swapped_arr [] = {unswapped_arr [N == swap_pair :: Pierwszy? swap_pair :: Po drugie: N == swap_pair :: Second? swap_pair :: First: N] ...}; 'gdzie masz tablicę niezapiętych elementów; możesz także użyć 'integer_sequence' z' get (seq) 'functions. – dyp

+1

[Przykład na żywo] (http://coliru.stacked-crooked.com/a/df8eac60c18156bc) – dyp

Odpowiedz

5

Link, który zamieściłem w komentarzu, to moja własna implementacja metafunkcji metafunkcji.

To, co zrobiłem, to przekształcenie parametrów wywołania bind z jego wartości (wartość lub symbol zastępczy) na wartość lub wartość reprezentowaną przez ten symbol zastępczy.

W twoim przypadku możesz spróbować podobnego podejścia: Odwzoruj sekwencję od symboli zastępczych (Wartości przekazane do zamiany) na odpowiadające wartości sekwencji. Coś jak:

template<std::size_t I> 
struct placeholder{}; 

using _1 = placeholder<0>; 
... //More placeholder aliases 

template<typename SEQ , typename... PLACEHOLDERS> 
struct swap; 

template<std::size_t... Is , std::size_t... Ps> 
struct swap<sequence<Is...>,placeholder<Ps>...> 
{ 
    template<typename PLACEhOLDER> 
    struct transformation; 

    template<std::size_t I> 
    struct transformation<placeholder<I>> 
    { 
     static constexpr const std::size_t result = get<sequence<Is...>,I>::value; 
    }; 

    using result = map<transformation,sequence<Is...>>; 
}; 

Gdzie map metafunkcji jest podobna do std::transform() (Bardzo łatwo pisać) i get metafunkcji która pobiera element i-ty sekwencji (łatwa).

ta może być wykorzystana w następujący sposób:

using swapped = typename swap<sequence<1,2,3>,_3,_2,_1>::result; //swapped is sequence<3,2,1> 
+1

@dyp Dzięki. Nigdy nie pisuj odpowiedzi na iPadzie ... – Manu343726