gpt4 book ai didi

c++ - 拆分 std::index_sequence 时出错

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:02:14 25 4
gpt4 key购买 nike

我正在尝试将 index_sequence 分成两半。为此,我生成了一个包含下半部分的 index_sequence,并使用它来跳过完整 index_sequence 中的前导元素。以下是代表我要实现的目标的最小测试用例:

template <int ...I>
struct index_sequence {};

template <int ...I, int ...J>
void foo(index_sequence<I...>, index_sequence<I..., J...>)
{}

int main()
{
foo(index_sequence<0>{}, index_sequence<0, 1>{});
}

我已经用最新版本的 ClangGCCMSVC 试过了,它们都无法推断出 J ...。这是标准允许的吗?如果不是,为什么以及什么是实现我的意图的好方法?

最佳答案

如果您想要拆分一个 std::index_sequence 而不是删除两个 std::index_sequence 的公共(public)前缀,我认为您可以从slice 的实现并使用它来将 std::index_sequence 分割成多个部分。

我将省略 std::index_sequence 和 friend 的实现,因为您可以引用论文 N3658 , 和一个示例实现 here .

制作索引范围

为了实现slice,我们将使用一个名为make_integer_range 的助手。我们需要一个 std::index_sequence 生成器,它给我们 [Begin, End) 而不是 [0, End)。利用 std::make_integer_sequence,我们得到:

template <typename T, typename Seq, T Begin>
struct make_integer_range_impl;

template <typename T, T... Ints, T Begin>
struct make_integer_range_impl<T, std::integer_sequence<T, Ints...>, Begin> {
using type = std::integer_sequence<T, Begin + Ints...>;
};

/* Similar to std::make_integer_sequence<>, except it goes from [Begin, End)
instead of [0, End). */
template <typename T, T Begin, T End>
using make_integer_range = typename make_integer_range_impl<
T, std::make_integer_sequence<T, End - Begin>, Begin>::type;

/* Similar to std::make_index_sequence<>, except it goes from [Begin, End)
instead of [0, End). */
template <std::size_t Begin, std::size_t End>
using make_index_range = make_integer_range<std::size_t, Begin, End>;

切片

由于我们没有 std::index_sequence 的类似 std::get 的功能或可变参数模板包,我们只是构建一个临时的 std::array 让我们 std::get。然后只用我们想要的切片来分解数组。

template <std::size_t... Indices, std::size_t... I>
constexpr decltype(auto) slice_impl(
std::index_sequence<Indices...>,
std::index_sequence<I...>) {
using Array = std::array<std::size_t, sizeof...(Indices)>;
return std::index_sequence<std::get<I>(Array{{Indices...}})...>();
}

template <std::size_t Begin, std::size_t End, std::size_t... Indices>
constexpr decltype(auto) slice(std::index_sequence<Indices...> idx_seq) {
return slice_impl(idx_seq, make_index_range<Begin, End>());
}

split 点

使用我们刚刚构建的 slice 的一个例子是编写一个 split_at 函数。我们指定要拆分 std::index_sequence 的索引,并返回一对在给定索引处拆分的 std::index_sequence

template <std::size_t At, std::size_t... Indices>
constexpr decltype(auto) split_at(index_sequence<Indices...> idx_seq) {
return std::make_pair(slice<0, At>(idx_seq),
slice<At, sizeof...(Indices)>(idx_seq));
}

split_at 示例:

static_assert(std::is_same<
decltype(split_at<2>(index_sequence<1, 4, 2>())),
std::pair<index_sequence<1, 4>, index_sequence<2>>>(), "");

static_assert(std::is_same<
decltype(split_at<1>(index_sequence<1, 4, 2, 3>())),
std::pair<index_sequence<1>, index_sequence<4, 2, 3>>>(), "");

关于c++ - 拆分 std::index_sequence 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20874388/

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