Yonatan Amir
Yonatan Amir

Reputation: 85

error in compilation while looping over map

got compilation error while trying to compile simple cpp program

i have tried the following compilation lines

1) gcc hello.cpp -std=gnu++11
2) g++ hello.cpp -std=gnu++11

this is my cpp file

#include <iostream>
#include <map>
#include <string>
using namespace std;
static map<string,int> create_map()
{
  map<string,int> mymap = {
                { "alpha", 10 },
                { "beta", 20 },
                { "gamma", 30 } };
  return mymap;
}
map<string,int> m=   create_map();   
int main() 
{
    cout << "Hello, World!";
    for (map<string,int> x: m) 
       cout << x.first << ": " << x.second << '\n';

    return 0;
}

the output of gcc contain a lot of linkage error like

hello.cpp:(.text+0x135): undefined reference to `std::cout'                             
hello.cpp:(.text+0x13a): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)

and g++ output was shorter

hello.cpp: In function 'int main()':
hello.cpp:19:29: error: conversion from 'std::pair<const std::basic_string<char>, int>' to non-scalar type 'std::map<std::basic_string<char>, int>' requested
hello.cpp:20:18: error: 'class std::map<std::basic_string<char>, int>' has no member named 'first'
hello.cpp:20:37: error: 'class std::map<std::basic_string<char>, int>' has no member named 'second'

the code is correct for 99.99%. i don't know really how to compile it properly

Upvotes: 0

Views: 72

Answers (3)

Mukul Gupta
Mukul Gupta

Reputation: 2425

Replace the loop with:

for (auto const& x: m) 
   cout << x.first << ": " << x.second << '\n';

Alternatively, you could use:

for (std::pair<string, int> x: m) 

or

for (const std::pair<string, int>& x: m) 

const because you do not want to change x. & to prevent a copy of the pair into x.

In the range based loop for an std::map, the variable that iterates over the container needs to be std::pair<const Key, T>. This is defined by the value_type for the container's Member types.

Upvotes: 2

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

There are some very different kind of errors you see.

gcc hello.cpp -std=gnu++11

This tries to compile the code using the GNU c-compiler.
C++ source files are recognized and compiled regarding the c++ syntax, but the linker uses c standard libraries, and the c++ standard libraries aren't automatically linked.

There must be some difference with your source, since I can't reproduce the linker errors you're claiming with this test.


In the other case

 g++ hello.cpp -std=gnu++11

your code is compiled using the c++ compiler, and

for (map<string,int> x: m)

is wrong regarding the type for x in the range based loop (which actually is pair<const string,int>).

You should simply change that to

for (const auto& x: m)

to get the code working.

x will be the type of the container element type, that is iterated over from m.

Here's a working online demo.

Upvotes: 3

Tetix
Tetix

Reputation: 331

Since the type of x is std::pair<const string,int> you need to use instead (after comments):

for (const std::pair<const string,int>& x: m)

const & is added so that redundant pair copies are avoided (in the newest compilers they are probably avoided any way).

for (const auto& x: m)

may alternatively be used!

Upvotes: 1

Related Questions