簡體   English   中英

可變參數模板包擴展參數ID

[英]Variadic template pack expansion argument id

我正在嘗試制作可變參數模板函數,以按順序讀取元素(帶有索引)。 例如,目標是調用函數read_tuple來讀取ID為0和1的兩個整數(具有read_int(0)和read_int(1))。

這是到目前為止我得到的代碼:

int data[] = {10,20,30,40};

int int_read(int id)
{
    return data[id];
}

template <typename T>
T read(int& index)
{
    index--;
    int value = int_read(index);
    std::cout << "index :" << index << " value: " << value << std::endl;
    return value;
}

template <typename... Args>
std::tuple<Args...> read_tuple()
{
    int index = sizeof...(Args);
    return std::tuple<Args...>(read<Args>(index)...);
}

我可以這樣稱呼它:

auto tuple = read_tuple<int, int>();
std::cout << "First: " << std::get<0>(tuple) << std::endl;

我得到以下輸出:

index :1 value: 20
index :0 value: 10
First: 10

但是,此代碼取決於讀取功能的評估順序。 如何生成依賴於包擴展的索引(以避免未定義的行為)?

正如Piotr所指出的,如果使用braced-init-list,則保證評估的順序。 但是,如果在4.9.1之前使用GCC,則要小心,因為它不起作用(請參閱braced-init-list中的初始化程序子句之間的評估順序(先后順序關系) )。

如果您使用的版本不保證初始化的順序(或者只想生成ID),則可以使用索引器(來自其他stackoverflow post ):

template<int... I> struct index {
    template<int n> using append = index<I..., n>;
};
template<int N> struct make_index {
    typedef typename make_index<N - 1>::type::template append<N - 1> type;
};
template<> struct make_index<0> { typedef index<> type; };
template<int N> using indexer = typename make_index<N>::type;

您可以這樣使用它:

int data[] = {10,20,30,40};

int int_read(int id)
{
    return data[id];
}

template <typename T>
T read(int index)
{
    int value = int_read(index);
    std::cout << "index :" << index << " value: " << value << std::endl;
    return value;
}

template <typename... Args, int... i>
std::tuple<Args...> read_tuple_indexed(index<i...>)
{
    return std::tuple<Args...>(read<Args>(i)...);
}

template <typename... Args>
std::tuple<Args...> read_tuple()
{
    return read_tuple_indexed<Args...>(indexer<(sizeof...(Args))>());
}

暫無
暫無

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

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