compilation error with const_reverse_iterator

  • Thread starter subramanian100in
  • Start date
S

subramanian100in

Consider the following program:

#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <algorithm>

using namespace std;

int main()
{
map<string, int> si;

string word;

while (cin >> word)
++si[word];

multimap<int, string> is;

for (map<string, int>::const_iterator i = si.begin(); i != si.end(); +
+i)
is.insert(make_pair(i->second, i->first));

for (multimap<int, string>::const_reverse_iterator r = is.rbegin(); r !
= is.rend(); ++r)
cout << r->second << " " << r->first << endl;

return 0;
}

Under g++, I get compilation error for the line

for (multimap<int, string>::const_reverse_iterator r = is.rbegin(); r !
= is.rend(); ++r)

The actual error message is

error: no match for 'operator!=' in 'r != std::multimap<_Key, _Tp,
_Compare, _Alloc>::rend() [with _Key = int, _Tp = std::string,
_Compare = std::less<int>, _Alloc = std::allocator<std::pair<const
int, std::string> >]()'

However this program compiles fine under VC++ 2005 Express Edition.

I use the following compilation command under g++.

g++ -std=c++98 -pedantic -Wall -Wextra word_count.cpp

Kindly explain why I am getting error for the above mentioned line
under g++ only.

Thanks
V.Subramanian
 
B

Barry

Consider the following program:

#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <algorithm>

using namespace std;

int main()
{
map<string, int> si;

string word;

while (cin >> word)
++si[word];

multimap<int, string> is;

for (map<string, int>::const_iterator i = si.begin(); i != si.end(); +
+i)
is.insert(make_pair(i->second, i->first));

for (multimap<int, string>::const_reverse_iterator r = is.rbegin(); r !
= is.rend(); ++r)
cout << r->second << " " << r->first << endl;

return 0;
}

Under g++, I get compilation error for the line

for (multimap<int, string>::const_reverse_iterator r = is.rbegin(); r !
= is.rend(); ++r)

Ah,
As you declare
>multimap<int, string> is;
then /is.rend()/ and /is.rbegin()/ are both reverse_iterators
r = is.begin(), compiles as is convertible from reverse_iterator to
const_reverse_iterator.

Threre are no /operator !=/ or /operator ==/ between the two types.

so you can simply choose reverse_iterator for r
The actual error message is

error: no match for 'operator!=' in 'r != std::multimap<_Key, _Tp,
_Compare, _Alloc>::rend() [with _Key = int, _Tp = std::string,
_Compare = std::less<int>, _Alloc = std::allocator<std::pair<const
int, std::string> >]()'

However this program compiles fine under VC++ 2005 Express Edition.

I think this is an extension from VC.
 
K

Kai-Uwe Bux

Consider the following program:

#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <algorithm>

using namespace std;

int main()
{
map<string, int> si;

string word;

while (cin >> word)
++si[word];

multimap<int, string> is;

Note that this is a non-const object.
for (map<string, int>::const_iterator i = si.begin(); i != si.end(); +
+i)
is.insert(make_pair(i->second, i->first));

for (multimap<int, string>::const_reverse_iterator r = is.rbegin(); r !
= is.rend(); ++r)

Note that is.rend() returns reverse_iterator and not const_reverse_iterator
since "is" is a non-const object. Thus, you compare

const_reverse_iterate != reverse_iterator

cout << r->second << " " << r->first << endl;

return 0;
}

Under g++, I get compilation error for the line

for (multimap<int, string>::const_reverse_iterator r = is.rbegin(); r !
= is.rend(); ++r)

The actual error message is

error: no match for 'operator!=' in 'r != std::multimap<_Key, _Tp,
_Compare, _Alloc>::rend() [with _Key = int, _Tp = std::string,
_Compare = std::less<int>, _Alloc = std::allocator<std::pair<const
int, std::string> >]()'

Yup. That's what you get.

However this program compiles fine under VC++ 2005 Express Edition.

I use the following compilation command under g++.

g++ -std=c++98 -pedantic -Wall -Wextra word_count.cpp

It's a matter which STL implementation you use.
Kindly explain why I am getting error for the above mentioned line
under g++ only.

You hit upon a defect in the language.

std::map<>::reverse_iterator is defined to be

std::reverse_iterator< std::map<>::iterator >

and std::map<>::const_reverse_iterator is defined to be

std::reverse_iterator< std::map<>::const_iterator >

The standard only requires that std::reverse_iterator supports comparison
for reverse_iterators with identical underlying iterator types. Thus, g++
is formally correct.

HOWEVER, this has been fixed in the draft for the next revision of the C++
standard. It also has been fixed in g++. Your code compiles fine with
g++-4.1.1.


Best

Kai-Uwe Bux
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top