作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个函数,从现有的 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/
我是一名优秀的程序员,十分优秀!