I am having a problem using const reverse iterators on non-const containers with gcc. Well, only certain versions of gcc.
#include <vector>
#include <iostream>
using namespace std;
int main() {
const char v0[4] = "abc";
vector<char> v(v0, v0 + 3);
// This block works fine
vector<char>::const_iterator i;
for (i = v.begin(); i != v.end(); ++i)
cout << *i;
cout << endl;
// This block generates compile error with gcc 3.4.4 and gcc 4.0.1
vector<char>::const_reverse_iterator r;
for (r = v.rbegin(); r != v.rend(); ++r)
cout << *r;
cout << endl;
return 0;
}
This program compiles OK and runs with gcc 4.2.1 (Mac Leopard) and with Visual Studio 8 and 9 (Windows), and with gcc 4.1.2 (Linux).
However, there is a compile error with gcc 3.4.4 (cygwin) and with gcc 4.0.1 (Mac Snow Leopard).
test.cpp:18: error: no match for 'operator!=' in 'r != std::vector<_Tp, _Alloc>::rend() [with _Tp = char, _Alloc = std::allocator<char>]()'
Is this a bug in earlier versions of gcc?
Due to other problems with gcc 4.2.1 on Mac, we need to use gcc 4.0.1 on Mac, so simply using the newer compiler is not a perfect solution for me. So I guess I need to change how I use reverse iterators. Any suggestions?
It is a defect in the current standard: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280
Edit: Elaborating a bit: The issue is that, in the current standard:
vector::reverse_iterator
is specified as std::reverse_iterator<vector::iterator>
, and vector::const_reverse_iterator
as std::reverse_iterator<vector::const_iterator>
.std::reverse_iterator
are defined with a single template parameter, making reverse_iterator<iterator>
and reverse_iterator<const_iterator>
non-comparable.In your code, you compare a const_reverse_iterator
with the result of calling "rend()" on a non-const vector, which is a (non-const) reverse_iterator
.
In C++0x, two related changes are made to fix issues like this:
In your case, a workaround would be to explicitely request the const_reverse_iterator for rend():
vector<char>::const_reverse_iterator r;
const vector<char>::const_reverse_iterator crend = v.rend();
for (r = v.rbegin(); r != crend; ++r)
cout << *r;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With