2014-06-11 10 views
6

Ben derleme zamanında variadic şablonunun iki parametre takas çalışıyorum:Derleme zamanında değişken bir şablonun iki parametresi nasıl değiştirilir?

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

kullanım durumu olmalıdır: düzgün olduğunu anlamaya olamaz

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 

Yazmanın yolu Swap_Data.

Ve varyantik parametrelerin değiştirilmesi ve derleme zamanında std :: array'e dönüştürmek için nasıl tekrarlamalı bir takas yapabilirim?

+0

Kontrol Bu https://github.com/Manu343726/Turbo/blob/reboot/bind.hpp gibi – Manu343726

+0

şey 'int swapped_arr [] = {unswapped_arr [N == swap_pair :: İlk? swap_pair :: Saniye: N == swap_pair :: İkincisi? swap_pair :: First: N] ...}; ''unsappapped elementlerin bir dizi var; '' (seq) 'işlevlerine sahip bir' integer_sequence 'de kullanabilirsiniz. – dyp

+1

[Canlı örnek] (http://coliru.stacked-crooked.com/a/df8eac60c18156bc) – dyp

cevap

5

Yorumda yayınlanan bağlantı, meta işlevler için benim bir std::bind() benzeri meta işlevini kendi uygulamamdır.

Yaptığım şey, bind çağrı parametrelerini değerinden (A değeri veya yer tutucu) bir değere veya o yer tutucu tarafından temsil edilen değere dönüştürmektir.

Sizin durumunuzda da benzer bir yaklaşımı deneyebilirsiniz: Diziyi yer tutuculardan (Takas edilen değerler) dizinin karşılık gelen değerleriyle eşleştirin. Bir şey gibi:

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...>>; 
}; 
map std::transform() benzer bir üst-işlevin (yazmak için çok kolay) 'dir

ve get (çok kolay) bir dizinin Ith elemanını alan bir üst-işlevin.

Bu

bu yolda kullanılabilir:

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

@dyp Teşekkürler. Bir iPad ile asla cevap yazmayın ... – Manu343726