Question

How do I map a key to a native data type like structure?

I wrote this snipped but I couldn't compile it. Do you have any ideas on how to fix it?

#include <map>
#include <iostream>

typedef struct _list
{
  int a,b;
}list;
map<int,list> test_map;

int main(void)
{
  cout <<"Testing"<< endl;
}
Was it helpful?

Solution

A number of problems here:

  • You're missing either a using::std or std::map, so the compiler doesn't know what map<int,list> means.

  • Assuming you have a using namespace std declaration, your typedef list might collide with the STL collection of the same name. Change the name.

  • Your typedef struct _tag {...} tag; construct is an archaic holdover from the 80's. It is not necesarry, and frankly rather silly. It gets you nothing.

Here's your code fixed:

#include <map>
#include <iostream>

struct MyList
{
  int a,b;
};

std::map<int,MyList> test_map;

int main(void)
{
  std::cout <<"Testing"<< std::endl;
  return 0;
}

OTHER TIPS

map resides in the std:: namespace. Two possible ways to fix this:

using namespace std;
// ...
map<int, list> test_map;

or

std::map<int, list> test_map;

I prefer the second method, but it's a purely personal choice.

On a related note, there is no real limitation on what you can put in a map, aside from the fact that they must be copyable/assignable, and that the key type must have a < operator (or you can also provide a comparer functor).

EDIT: Seems like <list> is included somewhere, either in <iostream> (unlikely) or <map> (strange but not impossible). A using namespace std will cause std::list to clash with your own struct. The solution: rename your struct, or remove the using namespace and put std:: where it's needed.

Added std where required.

Renamed list to mylist to avoid clash with std::list. Avoid typenames and variable names that clash with common usage.

Now compiles OK in VS2008.

#include <map>
#include <iostream>

typedef struct _list
{
    int a,b;
} mylist;

std::map<int,mylist> test_map;

int main(void)
{
    std::cout <<"Testing"<< std::endl;
    return 0;
}

There's no issue with using your struct in the STL containers provided it's copyable cleanly (copy constructor), assignable (implements operator=) and comparable (implements operator<).

map<int, _list> test_map; or don't use list(much better) as a name of structure. (You probably also have

#include <list>
...
using namespace std;

somewhere in your code.

I would try to avoid using codepad at all.

I have done a couple of tests with your code and it seems that

  • it is adding an implicit (and unwanted) using namespace std --it does not require you to qualify map, cout or endl.
  • it is (probably) including more standard headers than you might want, including #include <list>.

That means that when the compiler looks at the code it is seeing two list, your version and the one in std. Because of the using directive, both are in scope in the line where you create the map and the compiler is not able to determine which to use.

Two simple things that you can do: change the name of your type for the simple test to something other than list (ouch! the tool forcing your naming choices!) or fully qualify the use:

#include <map>
struct list {
   int a,b;
};
std::map< int, ::list > the_map;
// ...

Note that codepad is adding the include by itself and the using directive, so it will also compile:

struct list {
   int a,b;
};
map<int,::list> the_map;

But that piece of code is wrong

You seem to be comming from C. Try this:

#include <map>
#include <iostream>

struct list
{
  int a,b;
};

std::map<int,list> test_map;

int main(void)
{
  std::cout <<"Testing"<< std::endl;
  return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top