2014-09-05 23 views
5

Bir parametre paketini, tipik index_sequence & tuple numarasını kullanmadan ilk N - 1 ve Nth parametrelerine bölmek istiyorum ancak kafamı sarmış görünmüyor Çevresinde, yine de yapılabilir olması gerektiğinden eminim? (son öğeyi almak, özyineleme ile yeterince kolaydır).0 ... N-1 ve Nth öğesinde parametre paketini bölme

aramaya son işlev

void Fun(Foo a, Bar b); 

benziyor ve bir sırayla variadic birinden elde edilir:

template< class... T > 
Foo CalcFoo(T... args); 

Benim şu anki uygulama:

//get the last item of the pack 
template< class T > 
T split_last(T t){ return t; } 

template< class... T > 
T split_last(T, T... t){ return split_last(t...); } 

//helper 
template< class... T, size_t... Indices > 
Foo CalcFoo(const std::tuple<T...>& args, index_sequence<Indices...>) 
{ 
    return CalcFoo(std::get<Indices>(args)...); 
} 

//split and call 
template< class... T > 
void MoreFun(T... args) 
{ 
    //make a tuple containing all, then get n -1 items out of it 
    const auto tup = std::make_tuple<T...>(args...); 
    Fun(CalcFoo(tup, make_index_sequence< sizeof...(T) - 1 >()), 
     split_last(args...)); 
} 

güncelleme Bunu yapmaksızın nasıl yapılacağını bilmek istemek dışında Sadece bir iyilik için onu da sordum, çünkü bir şekilde bir tupenin başa çıkacağını düşündüm. Böylece, her zaman olduğu gibi, bir kez daha doğru olduğu ortaya çıkan, erken optimizasyon mantralarını görmezden geliyoruz. VS2013 ile serbest bırakma modunda derlenmiş hem benim hem Horstling'in kodu tam aynı montaj kodunu verir. CalcFoo dahil olmak üzere her şey, Fun numaralı çağrıya kadar numaralandırılmıştır. Başka bir deyişle: tuple tamamen gitti. Bu yüzden muhtemelen yine de bu uygulama ile uğraşacağım çünkü oldukça açık.

cevap

4

Tamam, yaratıcı olalım. Bunu yapmak için daha "standart" bir yolu vardır emin I`m ama Senle bu çözümü gibi;)

http://coliru.stacked-crooked.com/a/25a3fa276e56cd94

çekirdek fikirdir biz (eski ayırabilir kadar yinelemeli argümanlar döndürmek için) son argüman.

template <size_t N> 
struct MoreFunHelper 
{ 
    template <class Head, class... Tail> 
    static void RotateLeft(Head head, Tail... tail) 
    { 
     MoreFunHelper<N - 1>::RotateLeft(tail..., head); 
    } 
}; 

template <> 
struct MoreFunHelper<0> 
{ 
    template <class Head, class... Tail> 
    static void RotateLeft(Head head, Tail... tail) 
    { 
     Fun(CalcFoo(tail...), head); 
    } 
}; 

template< class... T > 
void MoreFun(T... args) 
{ 
    MoreFunHelper<sizeof...(T) - 1>::RotateLeft(args...); 
} 

yüzden argümanları

1 2 3 4 5 

onları döner 4 kez ile başlıyorsa:

2 3 4 5 1 
3 4 5 1 2 
4 5 1 2 3 
5 1 2 3 4 

Şimdi içine sorunsuz onları ayırabilirsiniz [5] ve [1 2 3 4 ], tam olarak istediğimiz budur. Bu noktada, yineleme durur ve sadece CalcFoo ve Fun işlevlerini çağırır.

+0

+1 Bu gerçekten de yaratıcı! – stijn