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_iteratoris specified asstd::reverse_iterator<vector::iterator>, andvector::const_reverse_iteratorasstd::reverse_iterator<vector::const_iterator>.std::reverse_iteratorare defined with a single template parameter, makingreverse_iterator<iterator>andreverse_iterator<const_iterator>non-comparable.In your code, you compare a
const_reverse_iteratorwith 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():