• Advertisement
Sign in to follow this  

I need a std::map wiz [SOS]

This topic is 4291 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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
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
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
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
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
Sign in to follow this  

  • Advertisement