gpt4 book ai didi

c++ - std::find() 在 C 风格数组上倒退?

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

假设我需要使用 s:

typedef struct tagSOMESTRUCT   // Defined by someone else; C-compatible
{
int count;
int elements[256];
} SOMESTRUCT;

SOMESTRUCT s;

然后说我有一个函数:

template<typename RevFwdIt>
std::pair<RevFwdIt, RevFwdIt> some_slice_rev(RevFwdIt rbegin, RevFwdIt rend)
{
RevFwdIt it = basename_rev(rbegin, rend);
RevFwdIt e = std::find(rbegin, it, 5);
return std::make_pair(e == it ? rbegin : e, it);
}

为了使用这个功能,我需要说

some_slice_rev(&s.elements[s.count - 1], &s.elements[-1]);

哪个(恕我直言)由于差一错误而变得丑陋且容易出错。

一方面,我不能简单地将 some_slice_rev 更改为 some_slice 以使用(更好)

some_slice(&s.elements[0], &s.elements[s.count]);

因为那时 std::find 会从头而不是结尾搜索。

另一方面,代码本身在我看来已经损坏了,因为我看不到 std::find 将如何处理作为原始指针的“反向迭代器”。

在这种情况下修复代码的最佳方法是什么?有什么方法可以使用作为原始指针的反向迭代器吗?或者是否有一个标准的重构机制来解决这个问题,其他而不是更改 SOMESTRUCT

最佳答案

我不太确定我是否理解这个问题(这可能是由于您似乎试图避免的迭代器方向的尴尬混合),但我只是将您的注意力引向 std::reverse_iterator:

#include <iostream>
#include <iterator>

// for example
template <typename Iter>
void print_it(Iter first, Iter last)
{
std::cout << '|';

for (; first != last; ++first)
std::cout << ' ' << *first << " |";

std::cout << std::endl;
}

int main()
{
int arr[10] = {1, 2, 3, 4};

int *begin = arr, *end = arr + 4;

print_it(begin, end);
print_it(std::reverse_iterator<int*>(end),
std::reverse_iterator<int*>(begin));
}

它们像双向迭代器一样工作,除了 ++ 在内部是 --,反之亦然。

请注意,它有点难看。您可能需要一些效用函数:

#include <iostream>
#include <iterator>

// for example
template <typename Iter>
void print_it(Iter first, Iter last)
{
std::cout << '|';

for (; first != last; ++first)
std::cout << ' ' << *first << " |";

std::cout << std::endl;
}

template <typename Iter>
std::reverse_iterator<Iter> make_reverse_iterator(Iter iter)
{
return std::reverse_iterator<Iter>(iter);
}

int main()
{
int arr[10] = {1, 2, 3, 4};

int *begin = arr, *end = arr + 4;

print_it(begin, end);
print_it(make_reverse_iterator(end),
make_reverse_iterator(begin));
}

所以我想你想要这个:

template<typename ForwardIterator >
std::pair<ForwardIterator, ForwardIterator>
some_slice(ForwardIterator begin, ForwardIterator end)
{
typedef std::reverse_iterator<ForwardIterator> rev_iter;

rev_iter it = basename(rev_iter(end), rev_iter(begin));
rev_iter e = std::find(rev_iter(end), it, 5);

return std::make_pair(it.base(), e.base());
}

现在相对偏离主题,但请注意,如果 s.count256,则 s.elements[s.count] 是未定义的行为,因为 s.elements[s.count]*(s.elements + s.count),它不是要取消引用的有效数组元素。

在实践中,完整的表达式很好,因为 &*x 抵消了 x,但您可能仍想避免它:

some_slice(s.elements, s.elements + s.count);

s.elements[-1] 也可能是未定义的行为,尽管我认为严格来说这可能是偶然合法的,因为你在 int 之前有一个成员数组。

关于c++ - std::find() 在 C 风格数组上倒退?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9850135/

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