Sign in to follow this  
Tradone

I need a std::map wiz [SOS]

Recommended Posts

Tradone    100
Okay, I know that this wouldn't compile b/c ["one"]["1"] is confusing for the compiler. He may think it's some sort of multidimentional array or something, I guess. Can you tell me who to fix this? I made a dummy:
#include <iostream>
#include <map>

using namespace std;
typedef map<string,map<string, string> > dmap;

int main(){
        dmap test;
        test.insert(pair< string, pair<string, string> >("one",make_pair("1","a")));
        cout << test["one"]["1"];

return 0;
}







145# g++ test2.cpp /usr/include/c++/3.4/bits/stl_pair.h: In constructor `std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = std::string, _U2 = std::pair<std::string, std::string>, _T1 = const std::string, _T2 = std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >]': test2.cpp:9: instantiated from here /usr/include/c++/3.4/bits/stl_pair.h:90: error: no matching function for call to `std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >::map(const std::pair<std::string, std::string>&)' /usr/include/c++/3.4/bits/stl_map.h:166: note: candidates are: std::map<_Key, _Tp, _Compare, _Alloc>::map(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >] /usr/include/c++/3.4/bits/stl_map.h:156: note: std::map<_Key, _Tp, _Compare, _Alloc>::map(const _Compare&, const typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::allocator_type&) [with _Key = std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >] /usr/include/c++/3.4/bits/stl_map.h:148: note: std::map<_Key, _Tp, _Compare, _Alloc>::map() [with _Key = std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >] ------------------------------------------------------------ This is the actual real problem, the reason I made the dummy. I know that the dummy program is nothing like the below original problem ( they are not anologies ) but I'd like to still know how to solve the dummy part as well, if members of gameDev can give me a helping hand! :D
typedef std::map<std::string,map<std::string, std::string> > DataMap;
std::map<std::string, std::string> *tempMap;
for( DataMap::reverse_iterator i=controlDirectoryInformation.GetFilesMap().rbegin(); i != controlDirectoryInformation.GetFilesMap().rend(); ++i ){
	for ( std::map<std::string, std::string>::iterator j=i->second.begin(); j != i->second.end(); ++j ){
		std::cout << "\t\t" << j->first << "=" << j->second << std::endl;
	}
	std::cout << "[" << i->first << "]"; // this is not a segmentation fault &  line 102 (see below for debugger Error)
	*tempMap=i->second;
	std::cout << (*tempMap)["name"]; // this is a segmentation fault
	std::cout << "[" << i->second["name"] << "]"; // this is also a segmentation fault
}





Errors: Program received signal SIGSEGV, Segmentation fault. 0x0805a46a in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_begin (this=0x0) at stl_tree.h:460 460 { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } (gdb) bt #0 0x0805a46a in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_begin (this=0x0) at stl_tree.h:460 #1 0x08062b21 in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::clear (this=0x0) at stl_tree.h:658 #2 0x08085742 in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::operator= (this=0x0, __x=@0x80a7894) at stl_tree.h:762 #3 0x08084f08 in std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::operator= (this=0x0, __x=@0x80a7894) at stl_map.h:218 #4 0x08081ff4 in Control::DisplayList (this=0x80a70c0) at Control.cpp:102 #5 0x08058c06 in main (argc=2, argv=0xbfbfec30) at new_shenu.cpp:210 ( --------------------------------------------------------------- while waiting for an answer I tried to make a dummy that actually is an anology of the original problem
#include <iostream>
#include <map>

using namespace std;
typedef map<string,map<string, string> > DataMap;

int main(){
        DataMap test;
        test.insert(pair< string, pair<string, string> >("one",make_pair("1","a")));
        test.insert(pair< string, pair<string, string> >("one",make_pair("2","b")));
        test.insert(pair< string, pair<string, string> >("two",make_pair("3","c")));
        test.insert(pair< string, pair<string, string> >("two",make_pair("4","d")));
        map<string,string> *tempMap;
        for( DataMap::reverse_iterator i=test.rbegin(); i != test.rend(); ++i ){
                for ( std::map<std::string, std::string>::iterator j=i->second.begin(); j != i->second.end(); ++j ){
                        std::cout << "\t\t" << j->first << "=" << j->second << std::endl;
                }
                std::cout << "[" << i->first << "]"; // this is not a segmentation fault &  line 102 (see below for debugger Error)
                *tempMap=i->second;
                std::cout << (*tempMap)["name"]; // this is a segmentation fault
                std::cout << "[" << i->second["name"] << "]"; // this is also a segmentation fault
        }

        //cout << test["one"]["1"];

return 0;
}




and once again defeated by compile Errors: ARRRR 145# g++ test2.cpp /usr/include/c++/3.4/bits/stl_pair.h: In constructor `std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = std::string, _U2 = std::pair<std::string, std::string>, _T1 = const std::string, _T2 = std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >]': test2.cpp:9: instantiated from here /usr/include/c++/3.4/bits/stl_pair.h:90: error: no matching function for call to `std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >::map(const std::pair<std::string, std::string>&)' /usr/include/c++/3.4/bits/stl_map.h:166: note: candidates are: std::map<_Key, _Tp, _Compare, _Alloc>::map(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >] /usr/include/c++/3.4/bits/stl_map.h:156: note: std::map<_Key, _Tp, _Compare, _Alloc>::map(const _Compare&, const typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::allocator_type&) [with _Key = std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >] /usr/include/c++/3.4/bits/stl_map.h:148: note: std::map<_Key, _Tp, _Compare, _Alloc>::map() [with _Key = std::string, _Tp = std::string, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, std::string> >] The errors seem to be due to the misuse of make_pair() I guess maps have different functions to insert like how I tried -------------------------------------------------------------- So, I try an even more manual method:
#include <iostream>
#include <map>

using namespace std;
typedef map<string,map<string, string> > DataMap;

int main(){
        DataMap test;
        map<string,string> *tempMap=new std::map;
        map.insert(pair< string, string>("1","a") );
        test.insert(pair< string, pair<string, string> >("one",*tempMap));
        map.insert(pair< string, string>("2","b") );
        test.insert(pair< string, pair<string, string> >("one",*tempMap));
        map.insert(pair< string, string>("3","c") );
        test.insert(pair< string, pair<string, string> >("one",*tempMap));
        map.insert(pair< string, string>("4","d") );
        test.insert(pair< string, pair<string, string> >("one",*tempMap));

        for( DataMap::reverse_iterator i=test.rbegin(); i != test.rend(); ++i ){
                for ( std::map<std::string, std::string>::iterator j=i->second.begin(); j != i->second.end(); ++j ){
                        std::cout << "\t\t" << j->first << "=" << j->second << std::endl;
                }
                std::cout << "[" << i->first << "]"; // this is not a segmentation fault &  line 102 (see below for debugger Error)
                *tempMap=i->second;
                std::cout << (*tempMap)["name"]; // this is a segmentation fault
                std::cout << "[" << i->second["name"] << "]"; // this is also a segmentation fault
        }

        //cout << test["one"]["1"];

return 0;
}

Encountered more errors. I must be dumb b/c I can't even fabricate a dummy. Anyway Errors: 145# g++ test2.cpp test2.cpp: In function `int main()': test2.cpp:9: error: `std::map' is not a type test2.cpp:10: error: missing template arguments before '.' token test2.cpp:11: error: no matching function for call to `std::pair<std::string, std::pair<std::string, std::string> >::pair(const char[4], std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)' /usr/include/c++/3.4/bits/stl_pair.h:69: note: candidates are: std::pair<std::string, std::pair<std::string, std::string> >::pair(const std::pair<std::string, std::pair<std::string, std::string> >&) /usr/include/c++/3.4/bits/stl_pair.h:85: note: std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] /usr/include/c++/3.4/bits/stl_pair.h:81: note: std::pair<_T1, _T2>::pair() [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] test2.cpp:12: error: missing template arguments before '.' token test2.cpp:13: error: no matching function for call to `std::pair<std::string, std::pair<std::string, std::string> >::pair(const char[4], std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)' /usr/include/c++/3.4/bits/stl_pair.h:69: note: candidates are: std::pair<std::string, std::pair<std::string, std::string> >::pair(const std::pair<std::string, std::pair<std::string, std::string> >&) /usr/include/c++/3.4/bits/stl_pair.h:85: note: std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] /usr/include/c++/3.4/bits/stl_pair.h:81: note: std::pair<_T1, _T2>::pair() [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] test2.cpp:14: error: missing template arguments before '.' token test2.cpp:15: error: no matching function for call to `std::pair<std::string, std::pair<std::string, std::string> >::pair(const char[4], std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)' /usr/include/c++/3.4/bits/stl_pair.h:69: note: candidates are: std::pair<std::string, std::pair<std::string, std::string> >::pair(const std::pair<std::string, std::pair<std::string, std::string> >&) /usr/include/c++/3.4/bits/stl_pair.h:85: note: std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] /usr/include/c++/3.4/bits/stl_pair.h:81: note: std::pair<_T1, _T2>::pair() [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] test2.cpp:16: error: missing template arguments before '.' token test2.cpp:17: error: no matching function for call to `std::pair<std::string, std::pair<std::string, std::string> >::pair(const char[4], std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<const std::string, std::string> > >&)' /usr/include/c++/3.4/bits/stl_pair.h:69: note: candidates are: std::pair<std::string, std::pair<std::string, std::string> >::pair(const std::pair<std::string, std::pair<std::string, std::string> >&) /usr/include/c++/3.4/bits/stl_pair.h:85: note: std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] /usr/include/c++/3.4/bits/stl_pair.h:81: note: std::pair<_T1, _T2>::pair() [with _T1 = std::string, _T2 = std::pair<std::string, std::string>] mmmmmmmmmkkkkkkkkkkkkkkkk... so..... these errors seem to be due to I HATE MAPS NOW! NO REALLY!! [Edited by - Tradone on April 24, 2006 5:30:08 PM]

Share this post


Link to post
Share on other sites
Enigma    1410
Problems 1 & 3: You are trying to insert a std::pair< std::string, std::pair< std::string, std::string > > into a std::map< std::string, std::map< std::string, std::string > >. You need to insert a std::pair< std::string, std::map< std::string, std::string > > instead.

Problem 2: tempMap is never initialised and therefore dereferencing it is an error and undefined behaviour. You need to make tempMap point to a real std::map< std::string, std::string > object before you can dereference it.

Σnigma

Share this post


Link to post
Share on other sites
Tradone    100
Okay, I'm sorry to ask, but can you do this for me?
I don't understand. Really.

Because, when I do insert on a plain map type for example
map<string,string> someMap;
I can insert like this:
someMap.insert([red]pair[/red]<string,string>("1","one") );


#include <iostream>
#include <map>

using namespace std;
typedef map<string,map<string, string> > dmap;

int main(){
dmap test;
test.insert(pair< string, pair<string, string> >("one",make_pair("1","a")));
cout << test["one"]["1"];

return 0;
}











I think the above is the same. No?
and can you fix that to a compilable code please?
I just can't get it figured out.




------------------------------------------------------------
So add the NULL right?
I keep getting the same seg fault, and I don't quite seem to understand your advice.

typedef std::map<std::string,map<std::string, std::string> > DataMap;
std::map<std::string, std::string> *tempMap=[red]NULL[/red];
for( DataMap::reverse_iterator i=controlDirectoryInformation.GetFilesMap().rbegin(); i != controlDirectoryInformation.GetFilesMap().rend(); ++i ){
for ( std::map<std::string, std::string>::iterator j=i->second.begin(); j != i->second.end(); ++j ){
std::cout << "\t\t" << j->first << "=" << j->second << std::endl;
}
std::cout << "[" << i->first << "]"; // this is not a segmentation fault & line 102 (see below for debugger Error)
*tempMap=i->second;
std::cout << (*tempMap)["name"]; // this is a segmentation fault
std::cout << "[" << i->second["name"] << "]"; // this is also a segmentation fault
}












Actually I used the pointer from above because this didn't work, So this is the original original work:

DirectoryInformation controlDirectoryInformation( "./system/db/" + controlParameter->Get("db") + "/data/", "date" );

typedef std::map<std::string, std::map<std::string, std::string>, case_insensitive_test> DataMap;

for( DataMap::reverse_iterator i=controlDirectoryInformation.[blue]GetFilesMap[/blue]().rbegin(); i != controlDirectoryInformation.GetFilesMap().rend(); ++i ){
for ( std::map<std::string, std::string>::iterator j=i->second.begin(); j != i->second.end(); ++j ){
std::cout << "\t\t" << j->first << "=" << j->second << std::endl;
}
std::cout << "[" << i->first << "]"; // this is not a segmentation fault & line 102 (see below for debugger Error)
std::cout << "[" << [red] i->second["name"] [/red] << "]"; // this is also a segmentation fault
}

//DirectoryInformation.h
class DirectoryInformation{
public:
std::map<std::string, std::map<std::string, std::string>, case_insensitive_test> GetFilesMap();

private:
std::map<std::string, std::map<std::string, std::string>, case_insensitive_test> filesMap;
//end private:
};

//DirectoryInformation.cpp
std::map<std::string, std::map<std::string, std::string>, case_insensitive_test> DirectoryInformation::[blue]GetFilesMap[/blue](){
return filesMap;
}

#endif










**wait, I think somebody once told me not to pass maps by value. So should I change GetFilesMap to return a &map<string, map<string, string> > ? I'm going to have to change A LOT OF THINGS if I do this. So I won't start until somebody confirms.**












------------------------------------------------------------

how can I delcare a map type on the heap?
map<string,string> someMap = new map;
doesn't seem to work.

Share this post


Link to post
Share on other sites
Xai    1848
no, the above isn't the same ... what you insert into a list, must be what that list holds ... period.

if you have a vector of ints, you insert ints ...

if you have a vector of vecotrs of ints, when inserting into the first item you must insert a vector of ints, not an int. when inserting into the child you would insert just an int.

so if you have this


// assume all headers and using std for readability

typedef map<string, map<string, map<int, map<int, void*> > > > TwoStringsAndTwoIntsToGenericPointer;

TwoStringsAndTwoIntsToGenericPointer myMap;

// you can see that
myMap["english"] -> a map of type map<string, map<int, map<int, void*> > >
myMap["english"]["hi"] - > a map of type map<int, map<int, void*> >
myMap["english"]["hi"][123] - > a map of type map<int, void*>
myMap["english"]["hi"][123][432] - > a void *

so to insert at each possible level, requires the appropriate matching pair type.

myMap - > insert with pair<string, map<string, map<int, map<int, void*> > > >
myMap["english"] -> insert with pair<string, map<int, map<int, void*> > >
myMap["english"]["hi"] - > insert with a pair<int, map<int, void*> >
myMap["english"]["hi"][123] - > insert with a pair<int, void*>
myMap["english"]["hi"][123][432] - > insert??? just use assignment


Share this post


Link to post
Share on other sites
Xai    1848
A cleaner partial example using typedefs and typedefed items:


typedef void* GenericPointerType;
typedef vector<GenericPointerType> GenericPointerList;
typedef vector<GenericPointerList> GenericPointerList2D;
typedef map<string, GenericPointerList2D> MapOfPointerList2D;
typedef map<string, PointerList2DMap> MapOfPointerList2DMap;

MapOfPointerList2DMap myMap;

// you can see that
myMap -> MapOfPointerList2DMap
myMap["english"] -> MapOfPointerList2DMap::value_type -> MapOfPointerList2D
myMap["english"]["hi"] -> MapOfPointerList2D::value_type -> GenericPointerList2D
myMap["english"]["hi"][123] -> GenericPointerList2D::value_type ->GenericPointerList
myMap["english"]["hi"][123][432] -> GenericPointerList::value_type -> GenericPointerType


Share this post


Link to post
Share on other sites
Tradone    100
okay I fixed the problem.

in conclusion: it's a bad idea to pass maps through value.
the iterator got distorted(?)

edit: Xia thanks a whole bunch, but that code does not compile.

#include <iostream>
#include <map>

using namespace std;
typedef map<string,map<string, string> > dmap;

int main(){
dmap test;
test["one"]["1"]["a"];
cout << test["one"]["1"];

return 0;
}



This right?

Share this post


Link to post
Share on other sites
discman1028    212
Original post by Tradone

#include <iostream>
#include <map>

using namespace std;
typedef map<string,map<string, string> > dmap;

int main(){
dmap test;
test["one"]["1"]["a"];
cout << test["one"]["1"];

return 0;
}







I kind of zoomed to the bottom of this thread, but the problem above seems to be that you need to assign "a" to test["one"]["1"]...

Try this:

typedef map<string,map<string, string> > dmap;
...
dmap test;
test["one"]["1"] = "a";
cout << test["one"]["1"]; // Should be "a"









"=" can be used instead of "insert()" for maps.

For the cout statement: test["one"] checks dmap for a mapping from "one" to a map<string, string>. Then since we have a map<string, string> now, the ["1"] checks for a mapping of "1" to some other string. It should be "a".

So try not to think of it as a multi-dimensional array. Each "[]" will resolve one mapping. Since you have nested mappings, you need to resolve twice.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this