我有一个DataIterator按需生成值的迭代器,因此取消引用运算符返回一个Data,而不是Data&.我认为这是一件好事,直到我试图通过将数据包装在reverse_iterator中来反转数据DataIterator.
DataCollection collection
std::reverse_iterator<DataIterator> rBegin(iter) //iter is a DataIterator that's part-way through the collection
std::reverse_iterator<DataIterator> rEnd(collection.cbegin());
auto Found = std::find_if(
rBegin,
rEnd,
[](const Data& candidate){
return candidate.Value() == 0x00;
});
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码时,它永远不会找到一个值等于0的Data对象,即使我知道一个存在.当我在谓词中插入一个断点时,我会看到奇怪的值,我永远不会期望看到像0xCCCC - 可能是未初始化的内存.会发生什么是reverse_iterator的解引用运算符看起来像这样(来自xutility - Visual Studio 2010)
Data& operator*() const
{ // return designated value
DataIterator _Tmp = current;
return (*--_Tmp); //Here's the problem - the * operator on DataIterator returns a value instead of a reference
}
Run Code Online (Sandbox Code Playgroud)
最后一行是问题所在 - 创建临时数据并返回对该数据的引用.该引用立即无效.
如果我将std :: find_if中的谓词更改为(数据候选者)而不是(const数据和候选者),那么谓词就可以了 - 但我很确定我只是幸运地遇到了未定义的行为.引用无效,但我在内存被破坏之前复制数据.
我能做什么?
给出下面的代码(说它的名字deque.cpp)
#include <cstdio>
#include <deque>
int main()
{
std::deque<int> d = {1, 2, 3};
for (auto it = d.rbegin(); it != d.rend();) {
printf("it: %d\n", *it);
++it;
d.pop_back();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译g++ -std=c++11 -o deque deque.cpp,运行良好:
$ ./deque
it: 3
it: 2
it: 1
Run Code Online (Sandbox Code Playgroud)
但如果编译为-D_GLIBCXX_DEBUG(g++ -std=c++11 -o deque_debug deque.cpp -D_GLIBCXX_DEBUG,它得到以下错误:
$ ./deque_debug
it: 3
/usr/include/c++/4.8/debug/safe_iterator.h:171:error: attempt to copy-
construct an iterator from a singular iterator.
...
Run Code Online (Sandbox Code Playgroud)
看起来第二个循环++it是从一个奇异的迭代器构造的.但我想在第一个循环之后++it,迭代器指向2,并且 …
我创建了一个简单的不可变双向迭代器:
#include <iostream>
#include <memory>
#include <iterator>
#include <vector>
#include <algorithm>
class my_iterator : public std::iterator<std::bidirectional_iterator_tag, int
//, std::ptrdiff_t, int*, int
> {
int d_val;
public:
my_iterator() : d_val(0) {}
my_iterator(int val) : d_val(val) {}
my_iterator operator--(int) { d_val--; return my_iterator(d_val + 1); }
my_iterator &operator--() { d_val--; return *this; }
my_iterator operator++(int) { d_val++; return my_iterator(d_val - 1); }
my_iterator &operator++() { d_val++; return *this; }
int operator*() const { return d_val; }
bool operator==(my_iterator const &o) …Run Code Online (Sandbox Code Playgroud) 我想在 aregex的背面使用 a string。
我可以执行以下操作,但我所有的sub_matches 都颠倒了:
string foo("lorem ipsum");
match_results<string::reverse_iterator> sm;
if (regex_match(foo.rbegin(), foo.rend(), sm, regex("(\\w+)\\s+(\\w+)"))) {
cout << sm[1] << ' ' << sm[2] << endl;
}
else {
cout << "bad\n";
}
Run Code Online (Sandbox Code Playgroud)
[现场示例]
我想要的是出去:
ipsum lorem
是否有任何规定可以获得不逆转的子匹配?也就是说,除了string像这样匹配后反转s之外的任何规定:
string first(sm[1]);
string second(sm[2]);
reverse(first.begin(), first.end());
reverse(second.begin(), second.end());
cout << first << ' ' << second << endl;
Run Code Online (Sandbox Code Playgroud)
编辑:
它已建议我更新的问题,以澄清我想要的东西:
运行regex的倒退string是没有关于扭转这一比赛被发现在顺序。该regex情况要复杂得多,这将是宝贵的,张贴在这里,但运行它向后节省了我从需要前瞻。这个问题是 …
在https://en.cppreference.com/w/cpp/iterator/reverse_iterator上说:
std::reverse_iterator是一个迭代器适配器,可反转给定迭代器的方向。换句话说,当提供了双向迭代器时,将std::reverse_iterator生成一个新的迭代器,该迭代器将从基础双向迭代器定义的序列的末尾移动到开头。对于由迭代器
r构造的反向迭代器i,该关系&*r == &*(i-1)始终为true(只要r是可取消引用的);因此,从一端到最后的迭代器构造的反向迭代器将引用序列中的最后一个元素。
因此,我尝试使用此代码来了解更多信息:
int main() {
std::deque<int> di{ 1, 1, 2, 3, 5, 8, 13 }; // fibonacci series
// deque has bi-directional iterators
std::deque<int>::iterator offEnd = di.end(); // one-past the last element in di
std::deque<int>::reverse_iterator r(offEnd); // constructing a reverse iterator from an iterator from deque<int> di
std::cout << &offEnd << " : " /*<< *r */ << std::endl;
std::cout << &(offEnd - …Run Code Online (Sandbox Code Playgroud) 如此处所示,向后迭代列表的一个好方法是使用rbegin(),如下所示:
list<DVFGfxObj*>::reverse_iterator iter = m_Objs.rbegin();
for( ; iter != m_Objs.rend(); ++iter) {
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不记得是否要++iter或--iter。因为我们正在倒退,所以使用--iter,对我来说似乎也是合乎逻辑的。
我正在寻求一个直观的解释,以便我能够永远记住它。我不想每次都查一下。
我(向前)遍历std :: map,并希望查找迭代器是否指向倒数第二个元素。我似乎找不到任何地方的方法。
我有:
bool
isSecondLastFile(const TDateFileInfoMap::const_iterator &tsFile)
{
TDateFileInfoMap::reverse_iterator secondLastIt = mFileInfoMap.rbegin() + 1;
return (tsFile == secondLastIt);
}
Run Code Online (Sandbox Code Playgroud)
TDateFileInfoMapstd :: map 在哪里
我越来越:
error: no match for ‘operator==’ in ‘tsFile == secondLastIt’
/usr/lib/gcc/i686-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:287: note: candidates are: bool std::_Rb_tree_const_iterator<_Tp>::operator==(const std::_Rb_tree_const_iterator<_Tp>&) const [with _Tp = std::pair<const long int, TFileInfo>]
Run Code Online (Sandbox Code Playgroud)
这是否意味着我无法比较正向和反向迭代器?
我如何确定正向迭代器是否指向倒数第二个元素?
+-- v.begin() +-- v.end()\n | |\n v v\n +---+---+---+---+---+---+ - +\n | o | o | o | o | o | o | x |\n +---+---+---+---+---+---+ - +\n\n+ - +---+---+---+---+---+---+\n| x | o | o | o | o | o | o |\n+ - +---+---+---+---+---+---+\n ^ ^\n | |\n +-- v.rend() +-- v.rbegin()\nRun Code Online (Sandbox Code Playgroud)\n(从这个答案中复制并编辑了 ASCII ,这实际上促使我提出当前的问题。)
\n我确实看到了这样做的好处&*rit == &*(rit.base() - 1),因为这样我就可以rit.base()对任何反向迭代器采用rit,并且我总是会得到一个有效的迭代器。
但同时
\nv.rbegin().base();我必须记住先减1 *(v.rbegin().base() …我试图通过移植Sedgewick和Wayne的第四版算法中的主要示例来提高我的C++技能.我根据他们的Java 示例编写了一个通用的堆栈实现.
我的堆栈工作正常,但我想提高性能并试图编写反向迭代器.
template<typename T> class ResizingArrayStack {
public:
T* begin() { return &array_ptr[0]; }
T* end() { return &array_ptr[N]; }
Run Code Online (Sandbox Code Playgroud)
...
// Here we're iterating forward through the array, with an unused variable `i`.
// It would be nice performance-wise to iterate in reverse without calling pop(), and without triggering a resize.
for ( auto& i : lifo_stack ) {
cout << "Current loop iteration has i = " << i << endl;
}
// // …Run Code Online (Sandbox Code Playgroud) 这是一个使用以下代码的示例std::reverse_iterator:
template<typename T, size_t SIZE>
class Stack {
T arr[SIZE];
size_t pos = 0;
public:
T pop() {
return arr[--pos];
}
Stack& push(const T& t) {
arr[pos++] = t;
return *this;
}
auto begin() {
return std::reverse_iterator(arr+pos);
}
auto end() {
return std::reverse_iterator(arr);
// ^ does reverse_iterator take this `one back`? how?
}
};
int main() {
Stack<int, 4> s;
s.push(5).push(15).push(25).push(35);
for(int val: s) {
std::cout << val << ' ';
}
}
// output is as expected: …Run Code Online (Sandbox Code Playgroud) 下面是我的 String 类的代码。我想实现 reverse_iterator 和 rbegin() 和 rend() 方法。已粘贴分配方法的代码。String::reverse_iterator rbegin = str2.rbegin(); String::reverse_iterator rend = str2.rend(); for(String::reverse_iterator b = rbegin; b!= rend;++b) { cout<<*b; }
class String {//my custom string class
public:
class iterator:public std::iterator<std::random_access_iterator_tag, char> {
public:
iterator():ch(NULL){}
iterator(const iterator& it) : ch(it.ch) {}
char& operator*() { return *ch; }
iterator& operator++() {
ch = ch+1;
return *this;
}
bool operator==(const iterator& rhs) {
return ch == rhs.ch;
}
bool operator!=(const iterator& rhs) {
return ch != rhs.ch;
} …Run Code Online (Sandbox Code Playgroud) 例如,下面的代码按 desc 顺序对 vec 进行排序:
std::vector<int> vec = {1, 2, 5, 4, 3};
sort(vec.rbegin(), vec.rend());
for(const auto v : vec)
std::cout << v << "\n";
output 5 4 3 2 1
Run Code Online (Sandbox Code Playgroud)
关于C++ 参考:
将范围 [first,last) 中的元素按升序排序。对于第一个版本,使用运算符 < 来比较元素 [...]
我使用了poll()和std :: vector.注册听socket.
std::vector<struct pollfd> fds;
fds.push_back(server_sock);
Run Code Online (Sandbox Code Playgroud)
并添加新的客户端套接字或连接的客户端会话.
// poll() ...
for(std::vector<struct pollfd>::reverse_iterator it = fds.rbegin(); it != fds.rend(); it++) {
if (it->fd == server_sock) {
struct pollfd newFd;
newFd.fd = newClient;
newFd.events = POLLIN;
fds.push_back(newFd);
} else {
// do something.
}
}
Run Code Online (Sandbox Code Playgroud)
但是当存在1或2或4个向量的元素时,reverse_iterator无法正常工作.我不明白为什么这项工作.
附上示例代码.
typedef struct tt_a {
int a;
short b;
short c;
} t_a;
vector<t_a> vec;
for (int i = 0; i < 1; i++) {
t_a t;
t.a = i;
t.b = i;
t.c = …Run Code Online (Sandbox Code Playgroud)