gpt4 book ai didi

c++ - 如何反转 `std::integer_sequence` 中整数的顺序?

转载 作者:行者123 更新时间:2023-12-05 02:28:17 26 4
gpt4 key购买 nike

有时我想反转 index_sequence 中的值并使用结果反转某些类似元组的值,就像这个反转中的值的插图编译时的 constexpr std::array

#include <array>
#include <cstdint>
#include <utility>

namespace detail {
template <class T, std::size_t N, std::size_t... I>
constexpr std::array<T, N> rev_arr_helper(const std::array<T, N>& arr,
std::index_sequence<I...>) {
return {arr[sizeof...(I) - I - 1]...};

// {arr[4-0-1], arr[4-1-1], arr[4-2-1], arr[4-3-1]}
// =>
// {arr[3], arr[2], arr[1], arr[0]}
}
} // namespace detail

template <class T, std::size_t N>
constexpr std::array<T, N> rev_arr(const std::array<T, N>& arr) {
return detail::rev_arr_helper(arr, std::make_index_sequence<N>{});
}

int main() {
constexpr std::array<int, 4> arr{11, 22, 33, 44};
constexpr auto rev = rev_arr(arr);
static_assert(rev[0] == 44 && rev[1] == 33 && rev[2] == 22 && rev[3] == 11, "");
}

现在,这种方法不适用于任何 integer_sequence,就像标题中的那样。它仅适用于那些有序的 0, 1, 2, ..., N-1 并且我希望能够使用 C++14 进行编译:

#include <type_traits>
#include <utility>

int main() {
std::integer_sequence<int, 4, -5, 7, -3> iseq;
std::integer_sequence<int, -3, 7, -5, 4> itarget;

auto irev = reverse_sequence(iseq);

static_assert(std::is_same<decltype(irev), decltype(itarget)>::value, "");
}

如何做到这一点?


以下是从评论中收集的一些相关问答:
How do I reverse the order of element types in a tuple type?

最佳答案

一个解决方案是创建一个 std::index_sequence能够模拟使用下标运算符访问 integer_sequence 中的值.通过输入整数序列,I... , 在 std::tuple一个可以使用 std::get<>提取 tuple 中某个位置的值.我们想要类似于 I[pos]... 的东西(如果有效)这就是我们得到的:

std::get<pos>( std::tuple<decltype(I)...>{I...} )...
  • 旁注:<decltype(I)...>上面是让它在 C++14 中工作所必需的。在 C++17 及更高版本中,可以简单地执行以下操作:
    std::get<pos>( std::tuple{I...} )...

把它放在适当的位置使得它非常类似于反转数组中的元素:

#include <cstddef>
#include <tuple>
#include <utility>

namespace detail {
template <class T, T... I, std::size_t... J>
constexpr auto rev_helper(std::integer_sequence<T, I...>, std::index_sequence<J...>)
{
return
std::integer_sequence<T,
std::get<sizeof...(J) - J - 1>(std::tuple<decltype(I)...>{I...})...>{};
// 𐌣 𐌣 / \
// index_sequence: └─── 3, 2, 1, 0 ───┘ integer_sequence: 4, -5, 7, -3
}
} // namespace detail

这将与示例 integer_sequence<int, 4, -5, 7, -3>然后扩展为类型:

std::integer_sequence<int,
std::get<3>(std::tuple<int,int,int,int>{4, -5, 7, -3}), // -3
std::get<2>(std::tuple<int,int,int,int>{4, -5, 7, -3}), // 7
std::get<1>(std::tuple<int,int,int,int>{4, -5, 7, -3}), // -5
std::get<0>(std::tuple<int,int,int,int>{4, -5, 7, -3}) // 4
>

与目标类型相同std::integer_sequence<int, -3, 7, -5, 4> .

辅助函数的前端只采用原始的 integer_sequence并使用 index_sequence 将其传递给助手:

template <class T, T... I>
constexpr auto reverse_sequence(std::integer_sequence<T, I...> seq) {
return detail::rev_helper(seq, std::make_index_sequence<sizeof...(I)>{});
}

Demo

关于c++ - 如何反转 `std::integer_sequence<int, 4, -5, 7, -3>` 中整数的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72706224/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com