I need a std::map wiz [SOS]

Started by
6 comments, last by discman1028 17 years, 12 months ago
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]
Advertisement
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
Yup, Enigma nailed it. Good job.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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.hclass 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.cppstd::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.
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 readabilitytypedef map<string, map<string, map<int, map<int, void*> > > > TwoStringsAndTwoIntsToGenericPointer;TwoStringsAndTwoIntsToGenericPointer myMap;// you can see thatmyMap["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
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 thatmyMap -> MapOfPointerList2DMapmyMap["english"] -> MapOfPointerList2DMap::value_type -> MapOfPointerList2DmyMap["english"]["hi"] -> MapOfPointerList2D::value_type -> GenericPointerList2DmyMap["english"]["hi"][123] -> GenericPointerList2D::value_type ->GenericPointerListmyMap["english"]["hi"][123][432] -> GenericPointerList::value_type -> GenericPointerType

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?
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.
--== discman1028 ==--

This topic is closed to new replies.

Advertisement