1

I'm very new to the use of STL containers in C++.

I have a map of 3 elements (2 strings as a pair - acting as the key, and an int acting as the value.)

map<pair<string, string>, int> wordpairs;

But when I try to iterate through it like this:

  for (map<pair<string, string>, int> iterator i = wordpairs.begin(); i != wordpairs.end(); i++) {
      cout << i->first << " " << i->second << "\n";
    }

the compiler is throwing errors:

     error: expected ‘;’ before ‘i’
         for (map<pair<string, string>, int> iterator i = wordpairs.begin(); i != wordpairs.
                                                      ^
    error: name lookup of ‘i’ changed for ISO ‘for’ scoping [-fpermissive]
    a7a.cpp:46:50: note: (if you use ‘-fpermissive’ G++ will accept your code)

   error: cannot convert ‘std::map<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >, int>::iterator {aka std::_Rb_tree_iterator<std::pair<const std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >, int> >}’ to ‘int’ in assignment
         for (map<pair<string, string>, int> iterator i = wordpairs.begin(); i != wordpairs.
                                                        ^
    error: no match for ‘operator!=’ (operand types are ‘int’ and ‘std::map<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >, int>::iterator {aka std::_Rb_tree_iterator<std::pair<const std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >, int> >}’)
         for (map<pair<string, string>, int> iterator i = wordpairs.begin(); i != wordpairs.
                                                                               ^    

    error: expected ‘)’ before ‘;’ token
     pair<string, string>, int> iterator i = wordpairs.begin(); i != wordpairs.end(); i++) {
                                                                                    ^
   error: expected ‘;’ before ‘)’ token
     pair<string, string>, int> iterator i = wordpairs.begin(); i != wordpairs.end(); i++) {

Not sure what I'm doing wrong here - this should be a simple fix though.

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
RockAndaHardPlace
  • 417
  • 1
  • 7
  • 18
  • 1
    shouldn't it be map, int>::iterator i ?? map, int> iterator i does not makes sense ... you are declaring two variable at once (iterator and i ) – solti Nov 06 '16 at 04:08
  • 1
    Using spaces where you need colons. – Peter Nov 06 '16 at 04:09
  • Thanks guys! That solved the problem! – RockAndaHardPlace Nov 06 '16 at 04:13
  • But now I have another problem: `error: no match for ‘operator<<’ ` at the line: `cout << i->first << " " << i->second << "\n";` This is unrelated to the original question though, I assume. – RockAndaHardPlace Nov 06 '16 at 04:14
  • 1
    @RockAndaHardPlace its because `i->first` is a pair .. So how would you print a pair? see this http://stackoverflow.com/questions/19228994/how-to-print-a-type-vectorpairchar-int-to-screen-c – solti Nov 06 '16 at 04:17

2 Answers2

3
  1. You got the type wrong (you used spaces instead of ::).

  2. Map iterator gives you a key value pair -- and your key is a pair! So you have a pair with a pair as a member. Here's an example that does roughly what you want to do.

    #include <iostream>
    #include <map>
    #include <string>
    #include <utility>
    using namespace std;
    
    int main() {
      pair<string, string> my_key("To", "Be");
      map<pair<string, string>, int> wordpairs { { {"Hello", "World"}, 33} };
      for (const auto& kv : wordpairs) {
        cout << kv.first.first << ", " 
             << kv.first.second << static_cast<char>(kv.second);
      }
      return 0;
    }
    
solti
  • 4,339
  • 3
  • 31
  • 51
druckermanly
  • 2,694
  • 15
  • 27
  • I did this: `cout << i.first.first << " " << i.first.second << "\n" << static_cast(kv.second);` but it is throwing errors. Also, not sure why we're using: `static_cast(kv.second)` – RockAndaHardPlace Nov 06 '16 at 04:34
  • 1
    If you're using an iterator, remember that they act like pointers. so instead of `i.first.first` you should use `i->first.first`. Also, the `static_cast(....)` was to be cute -- run my example through a C++11 compiler and see what the ensuing program does =). – druckermanly Nov 06 '16 at 04:35
  • I'm getting a weird character with binary digits on the output lol. – RockAndaHardPlace Nov 06 '16 at 04:37
  • You're probably doing `kv.second` instead of `kv->second`. – druckermanly Nov 06 '16 at 04:39
  • No I think it might have something to do with the `static_cast(....)`... I am getting the correct output with the strings themselves, but additional characters with them – RockAndaHardPlace Nov 06 '16 at 04:40
2

You forgot :: before iterator.
You can also use the auto keyword:

for (auto i = wordpairs.begin(); i != wordpairs.end(); ++i) {
  cout << i->first << " " << i->second << "\n";
}

or simply using the range-based for loop:

for (auto& i : wordpairs) {
  cout << i->first << " " << i->second << "\n";
}