Meh*_*dad 4 c++ pointers iterator find
说我需要使用s
:
typedef struct tagSOMESTRUCT // Defined by someone else; C-compatible
{
int count;
int elements[256];
} SOMESTRUCT;
SOMESTRUCT s;
Run Code Online (Sandbox Code Playgroud)
并说我有一个像以下的功能:
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);
}
Run Code Online (Sandbox Code Playgroud)
为了使用这个功能,我需要说
some_slice_rev(&s.elements[s.count - 1], &s.elements[-1]);
Run Code Online (Sandbox Code Playgroud)
哪个(恕我直言)由于一个一个错误而变得丑陋且容易出错.
一方面,我不能简单some_slice_rev
地some_slice
改为使用(好多了)
some_slice(&s.elements[0], &s.elements[s.count]);
Run Code Online (Sandbox Code Playgroud)
因为那时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));
}
Run Code Online (Sandbox Code Playgroud)
它们像双向迭代器一样工作,除了++
在内部--
,反之亦然.
请注意,它有点难看.您可能需要一些实用功能:
#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));
}
Run Code Online (Sandbox Code Playgroud)
所以我想你想要这个:
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());
}
Run Code Online (Sandbox Code Playgroud)
相对题外话了,但请注意,s.elements[s.count]
是不确定的行为,如果s.count
是256
,由于s.elements[s.count]
是*(s.elements + s.count)
,这不是一个有效的数组元素取消引用.
在实践中,完整的表达式很好,因为&*x
取消了x
,但你仍然可能想避免它:
some_slice(s.elements, s.elements + s.count);
Run Code Online (Sandbox Code Playgroud)
s.elements[-1]
也可能是未定义的行为,虽然我认为严格来说它可能是合法的,因为你int
在数组之前有一个成员.
归档时间: |
|
查看次数: |
2719 次 |
最近记录: |