gpt4 book ai didi

algorithm - 如何从元组中删除第n个元素?

转载 作者:行者123 更新时间:2023-12-02 22:22:44 25 4
gpt4 key购买 nike

我正在尝试编写一个函数,从现有的 std::tuple 创建一个新的 std::tuple ,并跳过给定索引上的元素。例如:

我有一个元组t定义如下:

constexpr auto t = std::tuple(1, 2, 3, 4);

我想将它复制到另一个元组。但是,我想跳过第 n 个元素。假设在本例中,我要跳过的第 n 个元素是 3(这意味着我要跳过索引为 2 的元素)。这将导致一个新的元组定义为:

std::tuple(1, 2, 4);

这是我迄今为止最接近的:

template<std::size_t N, typename T, std::size_t ... is>
constexpr auto fun(T&& tp, std::index_sequence<is...>&& i) noexcept {
return std::tuple((is != N ? std::get<is>(tp) : 0) ...);
}

template<std::size_t N, std::size_t... elems>
constexpr auto fun2() noexcept {
constexpr auto t = std::tuple(elems...);
return fun<N>(std::forward_as_tuple(elems...), std::make_index_sequence<sizeof...(elems)>());
}

但是,我没有删除第 n 个元素,而是将其设置为 0。

理想情况下,我会更改函数 fun() 中的返回参数,以使用多个临时元组创建一个新元组:

return std::tuple_cat((is != N ? std::tuple(std::get<is>(tp)) : std::tuple()) ...);

但是,这样做的问题是三元运算符两侧必须具有匹配的类型。

我尝试的另一种方法是基于递归:

template<std::size_t N, std::size_t head, std::size_t... tail>
constexpr auto fun3() noexcept {
if constexpr(!sizeof...(tail))
return std::tuple(head);

if constexpr(sizeof...(tail) - 1 == N)
return std::tuple_cat(fun3<N, tail...>());

if constexpr(sizeof...(tail) - 1 != N)
return std::tuple_cat(std::tuple(head), fun3<N, tail...>());
}

然而,这更不成功。在这种情况下,如果N等于0,则第n元素(也是这里的第一个元素)仍将在新元组中使用。另外,这甚至无法编译,因为第二条语句存在问题:

if constexpr(sizeof...(tail) - 1 == N)

我在这里缺少什么?如何复制元组并在复制过程中跳过其中的一个元素?

我使用的是 C++17,我需要在编译时评估该函数。

最佳答案

怎么样

return std::tuple_cat( foo<is, N>::func(std::get<is>(tp)) ...);

其中 foo 是一个具有如下专门化的结构?

template <std::size_t, std::size_t>
struct foo
{
template <typename T>
static auto func (T const & t)
{ return std::make_tuple(t); }
}

template <std::size_t N>
struct foo<N, N>
{
template <typename T>
static std::tuple<> func (T const &)
{ return {}; }
}

(警告:代码未经测试)。

这几乎是您的三元运算符想法,但不存在匹配两侧类型的问题:仅实例化正确的类型。

关于algorithm - 如何从元组中删除第n个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60289471/

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