2016-05-31 31 views
2

假設我們想創建一個幫助類來反轉模板包例如如下:是否有任何理由爲什麼使用std :: tuple傳遞C++模板包

#include <tuple> 
#include <utility> 
#include <typeinfo> 
#include <iostream> 

template <class> 
struct sizer; 

template <template<class...> class Pack, class... Args> 
struct sizer<Pack<Args...>> { 
    static constexpr size_t value = sizeof...(Args); 
}; 

template <class Pack, class Indices = std::make_index_sequence<sizer<Pack>::value>> 
struct reverse_pack; 

template <class... Args, size_t... I> 
struct reverse_pack<std::tuple<Args...>, std::integer_sequence<std::size_t, I...>> { 
    using type = typename std::tuple<typename std::tuple_element<(sizeof...(Args) - I - 1), std::tuple<Args...>>::type...>; 
}; 

int main() { 
    std::cout << typeid(reverse_pack<std::tuple<int, float, double>>::type).name() << std::endl; 
} 

我們可以成功地做到準確地使用例如同樣的事情函數簽名作爲模板參數:

#include <utility> 
#include <typeinfo> 
#include <iostream> 

template <class> 
struct sizer; 

template <class... Args> 
struct sizer<void(Args...)> { 
    static constexpr size_t value = sizeof...(Args); 
}; 

template <size_t N, class Sign> 
struct nth_param; 

template <size_t N, class First, class... Args> 
struct nth_param<N, void(First, Args...)>: nth_param<N-1, void(Args...)> { }; 

template <class First, class... Args> 
struct nth_param<0, void(First, Args...)> { 
    using type = First; 
}; 

template <class Pack, class Indices = std::make_index_sequence<sizer<Pack>::value>> 
struct reverse_pack; 

template <class... Args, size_t... I> 
struct reverse_pack<void(Args...), std::integer_sequence<std::size_t, I...>> { 
    using type = void(typename nth_param<(sizeof...(Args) - I - 1), void(Args...)>::type...); 
}; 

int main() { 
    std::cout << typeid(reverse_pack<void(int, float, double)>::type).name() << std::endl; 
} 

我與std::tuple(例如here)經驗表明其用於存儲數據,而不是傳遞的模板之間的類型包。那麼是否有任何實際的理由使用元組來操作變量?

+0

查看兩個代碼示例顯示縮短的長度,因爲不必重新創建tuple_element。 – chris

+2

函數參數類型可能不是數組,而元組元素類型可能是。 –

+2

函數簽名是錯誤的選擇。它調整其參數,例如一個函數被調整爲函數指針,常量被丟棄等。 –

回答

7

那麼是否有任何實際的理由使用tuple來操作變量?

一個tuple不對其參數進行任何轉換 - 一個tuple<int[2]>的確包含一個int[2]作爲其第一種類型,而void(int[2])真是void(int*)。這同樣適用於const,函數和其他類型的衰變。這使功能成爲不可行的選擇。

如果你寫你自己的類型串(如template <class... Ts> struct typelist{};),你仍然要重新實現std::getstd::tuple_elementstd::tuple_size。這是關於tuple的好事 - 它準備好並且有用。

而且大家已經知道std::tuple是什麼了。即使函數簽名不會以破壞它們的方式衰減它們的參數,我仍然會使用創建的類型作爲類型的異構容器 - 而不是將您的解決方案用於其他正常工作的解決方案。最不驚奇的原則和所有。

+3

但是它的缺點是很大:std :: tuple的體重很重,創建幾十或幾百個實例可能會使編譯時間縮短。 – Yakk

+0

@Yakk希望語言/庫會提前到'std :: tuple'不那麼重的地步。 – Barry

+0

是否可以使用'元組'在一個元組中存儲數組?我以爲你需要'std :: array <>'。你能解釋一下嗎? –

相關問題