tags:

views:

87

answers:

6

I am trying to write something like this. My question is 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 achieve this thing?

#include <map>
#include <iostream>

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

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

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.

Etienne de Martel
I added std:: before map, but it doesn't work
skokal01
Line 8: error: reference to 'list' is ambiguouscompilation terminated due to -Wfatal-errors.
skokal01
Please refer to the following source code...http://codepad.org/qhEwfQ8K
skokal01
Oh, yeah, I forgot to mention that you also need to add std:: before cout and endl.
Etienne de Martel
A: 

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;
}
Space_C0wb0y
Did you mean to say "You seem to be coming from C"?
Etienne de Martel
Yes...Dam right I am coming from "C"...ah good old days :D
skokal01
A: 

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.

a1ex07
+2  A: 

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<).

Steve Townsend
but how do insert values in to my test_map. For example how to do for test_map[0] I wanna insert a=1,b=2
skokal01
@skokal01 - Define a constructor on `mylist` that takes 2 ints, and then insert into the map like so : `test_map[0] = mylist(int1, int2);`
Steve Townsend
@Steve...wow thanks for the help...this was all new to me :)
skokal01
@skokal01 - plan on getting v familiar with your STL documentation. There is a ton of advice on this forum too if you search in a targeted way. You can also insert into the map using insert(make_pair) for example. The semantics of the [] insert are interesting and can be non-intuitive, take a look.
Steve Townsend
+1  A: 

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;
}
John Dibling
A: 

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

David Rodríguez - dribeas