簡體   English   中英

在編譯時生成相同類型的std :: tuple,其長度為模板參數

[英]Produce std::tuple of same type in compile time given its length by a template argument

在c ++中,如何使用指示元組長度的int模板參數實現一個函數並生成一個具有該長度的std :: tuple?

例如

func<2>() returns std::tuple<int, int>();
func<5>() returns std::tuple<int, int, int, int, int>().

這是一個帶有別名模板的遞歸解決方案,它可以在C ++ 11中實現:

template <size_t I,typename T> 
struct tuple_n{
    template< typename...Args> using type = typename tuple_n<I-1, T>::template type<T, Args...>;
};

template <typename T> 
struct tuple_n<0, T> {
    template<typename...Args> using type = std::tuple<Args...>;   
};
template <size_t I,typename T>  using tuple_of = typename tuple_n<I,T>::template type<>;

例如,如果我們想要"tuple of 3 doubles"我們可以寫:

tuple_of<3, double> t;

使用index_sequence和幫助器類型別名,您可以生成所需的類型:

// Just something to take a size_t and give the type `int`
template <std::size_t>
using Integer = int;

// will get a sequence of Is = 0, 1, ..., N
template <std::size_t... Is>
auto func_impl(std::index_sequence<Is...>) {
    // Integer<Is>... becomes one `int` for each element in Is...
    return std::tuple<Integer<Is>...>{};
}

template <std::size_t N>
auto func() {
    return func_impl(std::make_index_sequence<N>{});
}

值得一提的是,在一般情況下你可能會更好地使用std::array ,(在你的情況下你不能使用一個),但std::array行為就像一個元組,類似於std::pair

更新:既然你已經明確表示你正在使用c ++ 11而不是14+,那么你需要從某個地方獲得index_sequence的實現( 這里是libc ++)。 這是funcfunc_impl的C ++ 11版本,帶有顯式返回類型:

template <std::size_t... Is>
auto func_impl(std::index_sequence<Is...>) -> std::tuple<Integer<Is>...> {
  return std::tuple<Integer<Is>...>{};
}

template <std::size_t N>
auto func() -> decltype(func_impl(std::make_index_sequence<N>{})) {
  return func_impl(std::make_index_sequence<N>{});
}

普通的舊遞歸是你的朋友:

template<std::size_t N>
auto array_tuple() {
    return std::tuple_cat(std::tuple<int>{}, array_tuple<N-1>());
}

template<>
auto array_tuple<0>() {
    return std::tuple<>{};
}

如果你對C ++ 14解決方案沒問題,那么Ryan的答案可行的

使用C ++ 11,您可以執行以下操作(仍然基於index_sequence ,但這可以在C ++ 11中實現):

template <size_t N, class T, class = std::make_index_sequence<N>>
struct n_tuple;

template <size_t N, class T, size_t... Is>
struct n_tuple<N, T, std::index_sequence<Is...>> {
    template <size_t >
    using ignore = T;

    using type = std::tuple<ignore<Is>...>;
};

template <size_t N, class T>
using n_tuple_t = typename n_tuple<N, T>::type;

接着就,隨即:

template <size_t N>
n_tuple_t<N, int> func() {
    return n_tuple_t<N, int>{};
}

這里有兩個boost.hana解決方案(C ++ 14):

//first
hana::replicate<hana::tuple_tag>(int{}, hana::size_c<2>);

//second
hana::cycle(std::make_tuple(int{}), hana::size_c<2>);

兩者都產生大小為2的整數元組,但是它們不是std::tuple ,而是產生hana::tuple

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM