Cannot understand C++ map semantics - c++11

I don't understand the constructor statement in the following code. How can the iterator to the past-of-end element be added to the map as a key?
template<typename K, typename V>
class my_map {
std::map<K,V> m_map;
public:
my_map( V const& val) {
m_map.insert(m_map.end(),std::make_pair(std::numeric_limits<K>::lowest(),val));
}
};

How can the iterator to the past-of-end element be added to the map as a key?
It's not the key. It's the position of the insertion. By passing end you're saying append to the map.
The key that you're inserting is the first part of the pair. i.e. std::numeric_limits<K>::lowest().
The value that you're inserting is the second part of the pair. i.e. val.
The docs for std::map::insert are useful.

How can the iterator to the past-of-end element be added to the map as a key?
That's an incorrect conclusion. std::map::insert has several overloads. The one that is use in your call is:
iterator insert( iterator hint, const value_type& value ); // Overload 4
which does the following:
Inserts value in the position as close as possible, just prior, to hint.

Related

How to insert into a repeatedptrfiled just like vector.insert(iterator)

std::vector has a function to insert, which is
iterator insert(const_iterator _Where, const _Ty& _Val) { // insert _Val at _Where
return emplace(_Where, _Val);
}
is there any similar interface in repeatedptrfiled or some other way to insert into a repeatedptrfield by iterator but not index.
If you look at the docs here, there is nothing that allows you to set a value using an iterator. The closest thing is Set(int index, const Element& value) which is rather unfortunate. If you want to use a range based for loop but need Python-like element enumeration, consider using enumerate from CPPItertools.
Hy, the repeated field from protobuf is a std::vector and you can use the insert from it. Not very elegantly but it should work.

Iterating over const_iterator

ALL,
I have a function with the following signature:
void foo(const std::vector<Bar *> &myvec);
Inside this function I need to loop thru the members of the vector and perform some operations.
So, I tried this:
for( std::vector<Bar *>::const_iterator it = myvec.begin(); it < myvec.end(); ++it )
{
// modify properties of Bar * pointer
(*it)->SetSomeValue( baz );
}
however this code asserts since the iterator is constant.
Now obviously the vector is constant, which means that the function shouldn't be modifying myvec.
What's the best solution here?
Can I use const_cast here to remove constness? It would be kind of hack-ish, but if it works.
But I feel there must be a better solution.
TIA!!
You should use the myvec.cbegin() method instead of myvec.begin(), to ensure that you are not modifying the object the iterator points to.
Of course, for myvec.end(), use myvec.cend() accordingly.
The iterator itself doesn't need to be a const_iterator, in the contrary, you want to modify the objects it gives you - set_...() sounds like a non-const activity.

Convert Boost::Map iterator to std::iterator

I was writing wrapper methods for Boost unordered map container. In boost Unordered Map there is a method begin() which returns an iterator to the first element.Actually in my wrapper class i want to return a std::Unordered_map::iterator instead of boost::unordered_map::iterator from my Begin method.
Example code:
template
boost::unordered_map<key, value> m_myMap;
boost::unordered::unordered_map::iterator MyWrapper<>::Begin()
{
return m_myMap.begin();
}
In the above code i want to return std::Unordered_map::iterator
Please help
You can't. C++ is a strongly typed language.
The best you can do is
use std::unordered_map
Use type erasure to hide the implementation (boost::any_iterator or boost::any_range)
My spidy sense tells me that you should take the iterators by deduced template argument type, instead of hard-coding them into your algorithms.
template <typename Iterator>
void foo_algo(Iterator begin, Iterator end, int some_data) {
...

C++11 lock free stack

I'm reading C++ Concurrency in Action by Anthony Williams, and don't understand its push implementation of the lock_free_stack class.
Why on earth the atomic load is not in the while loop ? The reason he gave is:
You therefore don’t have to reload head each time through the loop,
because the compiler does that for you.
But I don't get the picture. Can someone shed some light on this?
template<typename T>
class lock_free_stack
{
private:
struct node
{
T data;
node* next;
node(T const& data_) :
data(data_)
{}
};
std::atomic<node*> head;
public:
void push(T const& data)
{
node* const new_node=new node(data);
new_node->next=head.load();
while(!head.compare_exchange_weak(new_node->next,new_node));
}
};
The key is in the interface to compare_exchange_weak, which in this case takes 2 arguments. The first is a reference to the expected value, and the second is the desired. If the current value of the atomic is not equal to the expected input, it will return false and the expected input is set to the current value.
So in this case, what it's doing is setting new_node->next = head. Then, it's saying if head is still equal to new_node->next, swap it into head. If it's no longer that value, it uses the reference to new_node->next to assign it the current value of head. Since every iteration of the loop that fails also replaces new_node->next with the current value of head, there is no read to duplicate that in the body of the loop.
From the documentation of compare_exchange_weak:
Atomically compares the value stored in *this with the value of
expected, and if those are equal, replaces the former with desired
(performs read-modify-write operation). Otherwise, loads the actual
value stored in *this into expected (performs load operation).
As you see, otherwise the actual value of head is loaded into expected.

In unordered_map of C++11, how to update the value of a particular key?

In Java's hashmap:
map.put(key, new_value)
will update the entry of key=key with new_value if it exists in the hashmap.
What's the correct way to do the similar thing in unordered_map of C++11?
I haven't found an API like updateXXX, and the documentation says the unordered_map::insert function will succeed only when there isn't any such pair with a key.
If you know that the key is in the map, you can utilize operator[] which returns a reference to the mapped value. Hence it will be map[key] = new_value. Be careful, however, as this will insert a (key, new_value) if the key does not already exist in the map.
You can also use find which returns an iterator to the value:
auto it = map.find(key)
if(it != map.end())
it->second = new_value;
If the type value has no default constructor you can use:
map.emplace(key, new_value).first->second = new_value;
This also has all the other advantages of emplace vs [] operator and insert.
I thought that Java's map.put inserted the element if it wasn't already in the map and updated it if it was in the map, see put:
put
public V put(K key, V value)
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.
This would be equivalent to unordered_map::operator[]:
If k matches the key of an element in the container, the function returns a reference to its mapped value.
If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).
Check if the key exists
Update the value by referencing the key
if(map.count(key)){
map[key] = value;
}

Resources