簡體   English   中英

通過將兩個參數包的元素線程化為成對的類型來解包

[英]Unpacking two parameter packs by threading their elements to pairs of types

給定說N用戶指定的類型,我想要一個函數來返回長度為Nstd::tuple ,其中每個元素都是通過對某個函數的函數調用構造的(以下以func為例):

#include <tuple>
#include <utility>

template <typename T> 
T func(int x)
{
    return T();
}

template<typename... T, std::size_t... I> 
std::tuple<T...> build_tuple()
{
    // How do I write this in a generic way?
    return std::make_tuple(
        func<std::string>(0),
        func<int>(1),
        func<int>(2)
        );

    // This won't work, obviously
    // return std::make_tuple(func<T...>(I...));
}

int main() 
{
    build_tuple<std::string, int, int>();
}

本質上,我的問題是如何解壓縮參數以沿“ type0,0”,“ type1、1”等行獲取內容,而不是“ type0,type1,...,0、1 ...” ,如果有道理。

這感覺像是一個普遍的問題,所以有慣用的解決方案嗎?

如果size_t參數為0, 1, ... ,則可以簡單地使用其他間接級別:

template<class Tuple, std::size_t... I> 
Tuple build_tuple_impl(std::index_sequence<I...>)
{
    return std::make_tuple(
        func<std::tuple_element_t<I, Tuple>>(I)...);
}

template<typename... Ts> 
auto build_tuple()
{
    using Tuple = std::tuple<Ts...>;
    return build_tuple_impl<Tuple>(std::make_index_sequence<sizeof...(Ts)>{});
}

// Usage:
auto t = build_tuple<std::string, int, int>();

更一般的情況:

template<class Tuple, std::size_t... Is, std::size_t... I> 
Tuple build_tuple_impl(std::index_sequence<Is...>, std::index_sequence<I...>)
{
    constexpr std::size_t is[] = {Is...};
    return std::make_tuple(
        func<std::tuple_element_t<I, Tuple>>(is[I])...);
}

template<typename... Ts, std::size_t... Is>
auto build_tuple(std::index_sequence<Is...> is)
{
    static_assert(sizeof...(Ts) == sizeof...(Is));

    using Tuple = std::tuple<Ts...>;
    return build_tuple_impl<Tuple>(is, std::make_index_sequence<sizeof...(Ts)>{});
}

// Usage:
auto t = build_tuple<std::string, int, int>(std::index_sequence<3, 4, 5>{});

不是說你不能寫build_tuple<std::string, int, int, 3, 4, 5>() 序列之一應打包為單一類型。

暫無
暫無

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

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