I add the constructor and two functions to the class of my previous linked question C++ iterate through a template Map and I need help at this points:
- What do you reckon this constructor does?
- Adding one value at the beginning of map?
- I see though in the respective key only an address as value after initializing in main. What is wrong?
The operator [] is supposed to get the values for a specific key. However I cannot use it so as to get the elements of the map in the output. Any hint?
template<class K, class V>
class template_map{
public:
template_map( V const& val) {
m_map.insert(my_map.begin(),std::make_pair(std::numeric_limits<K>::min(),val));
};
typedef typename std::map<K,V> TMap;
TMap my_map;
typedef typename TMap::const_iterator const_iterator;
const_iterator begin() const { return my_map.begin(); }
const_iterator end() const { return my_map.end(); }
V const& operator[]( K const& key ) const {
return ( --my_map.upper_bound(key) )->second;
}
...
};
int main()
{
interval_map<int,int> Map1 (10);
//Show the elements of the map?
}
Consider also that it should be a function that inserts values to the map.
What do you reckon this constructor does? Adding one value at the beginning of map?
It initialises the map so that map[x] == v
for any x
. The map associates intervals with values, internally storing a normal map keyed by the start of each interval; it's initialised so that the entire range of the key type maps to the initial value.
I see though in the respective key only an address as value after initializing in main. What is wrong? The operator [] is supposed to get the values for a specific key. However I cannot use it so as to get the elements of the map in the output. Any hint?
I've no idea what you're asking there. If you try, for example, cout << Map1[42] << '\n';
, then your program should output 10
, since that is the initial value assigned to the entire range of integers.
Consider also that it should be a function that inserts values to the map.
Since the internal map is publicly exposed, you can add a new interval to the map with
Map1.my_map.insert(std::make_pair(interval_start, value));
It might be more polite to make my_map
private, and provide an insert()
function to do that. You could also add a non-const overload of operator[]
that inserts a new range and returns a reference to its value, something like
V & operator[](K const & key) {
V const & old_value = (--my_map.upper_bound(key))->second;
return *my_map.insert(std::make_pair(key, old_value)).first;
}
although this might not be a great idea, as you'd have to be careful that you don't accidentally insert many ranges when you only want to read the values.
My problem is how to iterate through the map to get all its elements and print them in main. It shows me an address with a value of the object initialization.
Remembering that an iterator over a map refers to a key/value pair (of type std::pair<K,V>
), you should be able to iterator over the map like this:
for (auto it = Map1.begin(); it != Map1.end(); ++it) {
std::cout << it->first << " maps to " << it->second << '\n';
}
(in C++03, you'll need to write template_map<int,int>::const_iterator
rather than auto
).
What do you reckon this constructor does? Adding one value at the
beginning of map? I see though in the respective key only an address
as value after initializing in main. What is wrong?
It adds this one value in to the map. The iterator argument is only a hint: if the new item is to be inserted right after this position, the operation can be completed faster. Otherwise the map will need to find the right place to insert the new value as usual.
The operator [] is supposed to get the values for a specific key.
However I cannot use it so as to get the elements of the map in the
output. Any hint?
upper_bound
returns iterator to the first key-value pair, where key is greater than the argument. --upper_bound
therefore returns an iterator to the item, whose key is either equal or less than the queried key. If upper_bound
returned map.begin()
, because all keys are greater than the query, decrementing it is undefined behavior.
What you need here is the find
member function. You also need to deal with the case the key is not found (map.end()
is returned), e.g by throwing an exception.
Alternatively you may implement your operator[]
in terms of map::operator[]
. This means that the function can't be const, because map inserts a new default value if the key is not found.
The iterator in map::insert()
is just a hint; essentially it doesn't mean anything in terms of the semantics of the program.
Your code inserts the value passed through the constructor argument together with the key numeric_limits<K>::min()
, i.e. the smallest possible value for the given key type. This will only complile if numeric_limits
is specialized for the type K
.
Also note that if the key already exists, the corresponding mapped value will not be overwritten, so a corresponding insert function would be of very limited use.