map of map initialization - c++

I am trying to initialize a map of map but I am unsure what mistake I am doing. Below is the sample code.
static std::map<std::string, std::map<std::string,std::string>> _ScalingMapVolume ={
{"AA",{"busy_timeout","test"}},
{"BB",{"cache_size","10000"}}
};
The error I am getting is;
error: no match for call to ‘(std::_Select1st<std::pair<const std::basic_string<char>, std::basic_string<char> > >) (const char&)’

{"busy_timeout","test"} is not the value of a map, but a pair. You need {{"busy_timeout","test"}}.
Your code should look like this:
static std::map<std::string, std::map<std::string, std::string>> _ScalingMapVolume = {
{"AA", {{"busy_timeout", "test"}}},
{"BB", {{"cache_size", "10000"}}}
};

init = {{"AA", {"busy_timeout", "test"}}, ...}
You are missing one set of braces, since the value_type of the map is std::pair<const std::string, std::map<std::string, std::string>>. The value_type of the mapped_type is
std::pair<const std::string, std::string>. So you need to use it that way.

Related

Insert Pair as a key in map using c++

I want to know how can insert pair in map using c++, here's my code:
map< pair<int, string>, int> timeline;
I tried to insert it using:
timeline.insert(pair<pair<int, string> , int>(make_pair(12, "str"), 33);
//and
timeline.insert(make_pair(12, "str"), 33);
but I got error
\main.cpp|66|error: no matching function for call to 'std::map<std::pair<int, std::basic_string<char> >, int&>::insert(std::pair<int, const char*>, int)'|
std::map::insert expects std::map::value_type as its argument, i.e. std::pair<const std::pair<int, string>, int>. e.g.
timeline.insert(make_pair(make_pair(12, "str"), 33));
or simpler as
timeline.insert({{12, "str"}, 33});
If you want to construct element in-place you can also use std::map::emplace, e.g.
timeline.emplace(make_pair(12, "str"), 33);
LIVE
When in doubt, simplify.
auto key = std::make_pair(12, "str");
auto value = 33;
timeline.insert(std::make_pair(key, value));
Simply use the traditional way:
timeline[key] = value;
For instertion and retrival of pair:
timeline[{1,"stackOverFlow"}] = 69;
for(auto i: timeline)
{
cout<< i.first.first;
cout<< i.first.second;
cout<< i.second;
}

adopt back_inserter to insert to list from map using boost iterator adopters

std::copy(map.begin(), map.end(), std::back_inserter(list)) this is what I am trying to achive.. take i->second items from map to list. Is there any boost iterator adopters that I can use ?
I thought transform_iterator will work. and this is how I was trying to do.
std::map<int, std::string> map;
std::list<std::string> list;
std::copy(
boost::make_transform_iterator(map.begin(),
boost::bind(&std::pair<int, std::string>::second, _1)),
boost::make_transform_iterator(map.end(),
boost::bind(&std::pair<int, std::string>::second, _1)),
std::back_inserter(list));
I am actually applying on std::set_intersection That doesn't take a functor as function parameter So I cannot use std::transform and pass a function. (attaching actual code)
typedef std::map<khut::point::value_type, khut::diagonal> storage_type;
storage_type repo_begining;
storage_type repo_ending;
storage_type::const_iterator lower_it = repo_begining.lower_bound(diagonal.begining().y());
storage_type::const_iterator upper_it = repo_ending.lower_bound(diagonal.ending().y());
std::list<khut::diagonal> diagonals_intersecting;
std::set_intersection(lower_it, repo_begining.end(), repo_ending.begin(), upper_it, std::back_inserter(diagonals_intersecting));
Note: I cannot use C++11
The problem is in value_type. std::map<int, std::string>::value_type is not std::pair<int, std::string> it is std::map<const int, std::string> So once I changed the code to
std::copy(
boost::make_transform_iterator(map.begin(),
boost::bind(&std::pair<const int, std::string>::second, _1)),
boost::make_transform_iterator(map.end(),
boost::bind(&std::pair<const int, std::string>::second, _1)),
std::back_inserter(list));
It worked

insert a std::initializer_list into std::map

I have a method like this:
std::map<std::string, int> container;
void myMap(std::initializer_list<std::pair<std::string, int>> input)
{
// insert 'input' into map...
}
I can call that method like this:
myMap({
{"foo", 1}
});
How I can convert my custom argument and insert into the map?
I tried:
container = input;
container(input);
But don't work because the parameter of map is only std::initializer_list and there's no std::pair there.
Thank you all.
container.insert(input.begin(), input.end());
If you want to replace the contents of the map. do container.clear(); first.
Your problem is that the value_type of std::map<std::string,int> is not
std::pair<std::string,int>. It is std::pair<const std::string, int>. Note the const on the key. This works fine:
std::map<std::string, int> container;
void myMap(std::initializer_list<std::pair<const std::string, int>> input) {
container = input;
}
If you can't change your function's signature, you have to write a loop or use std::copy to convert each input element into the value_type of the container. But I'm guessing you probably can, since it's called myMap and not otherGuysMap :) .

assignment operator with maps

map<char *, int> sym_addr;
map<char *, int> sym_tbl;
void set_map(map<char *, int> & sym_tbl)
{
sym_addr = sym_tbl;
}
Is there any problem with the above assignment?
A better way would be to change the keys to std::string : std::map< std::string, int>
If you want to copy, pass that object by const reference:
typedef std::map< std::string, int> myMapType;
myMapType sym_addr;
myMapType sym_tbl;
void set_map(const myMapType & sym_tbl)
{
sym_addr = sym_tbl;
}
Other then that, there are no problems. map::operator= is used to copy the content of one map into another.
You should pass the argument by const reference, otherwise you prevent copying a map declared const.
Also, make sure you understand exactly what happens if you use char* as a key - the key is the address of the string, not its contents. If you want to index the map by string values, use std::string as the key.

Inserting item into map, which holds 2 more map

I am trying to insert an item, into a map, which holds two other map.
map< map<int, int> , map<int, int> > GC;
map<int, int> A;
A.insert(pair<int,int>(1,1));
map<int, int>:: iterator p1 = A.begin();
map<int, int> B;
B.insert(pair<int,int>(2,3));
map<int, int>:: iterator p2 = B.begin();
GC.insert( pair< map<int,int>, map<int,int> > (*p1, *p2) );
Well, as presumed its not working.
How to do it?
EDIT:
It gives the following error:
E:\CB\test.cpp|20|error: no matching function for call to 'std::pair<std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >, std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > > >::pair(std::pair<const int, int>&, std::pair<const int, int>&)'
I am not sure what are trying to achieve here .....
Your key and value needs to be an map object in order to work...
In that case only possibility is
GC.insert( pair< map<int,int>, map<int,int> > (A,B) );
I think you really want a Node class with a list/vector of Edge objects. Each Edge object would contain the edge weight and a pointer to the Node that edge connected to.
There may be better ways to create a graph than I have described, but this should get you thinking in the right direction.
map<keyValue, VertexIndexValue>, map<(EdgeWeight1,VertexIndexValue1), (EdgeWeight2,VertexIndexValue2)......>
I think what you want is to use a structure as the second element of your map. It gives you the chance to hold whatever you want in the map without it getting confusing.
struct sMapValue
{
int mVertIndex;
map<int, int> mVertEdgeMap;
};
map< int, sMapValue> GC;