I know that it's a terrible idea to change the key of an object in an associative container, but I wonder where exactly the standard forbids me to do so. Consider:
#include <map>
#include <memory>
struct X { int i; };
struct lt
{
bool operator()( const std::shared_ptr< X >& lhs,
const std::shared_ptr< X >& rhs ) const
{
return lhs->i < rhs->i;
}
};
int main()
{
std::map< std::shared_ptr< X >, int, lt > m;
auto x = std::make_shared< X >();
x->i = 1;
m.insert( std::make_pair( x, 2 ) );
x->i = 42; // change key wrt the container!
}
I assume that the above should be illegal, but I was reading the standard for some time now and I can't find anything that actually makes it illegal. Where is it? Or is it hiding in a future defect report?
So what makes it associative? The fact that elements in a set are referenced by their key and not by their absolute position in the container. The key, of course, is the element itself. Think of it as a map where the keys are values are equal and given that, where the duplicate copy of the same content is eliminated.
C++ map update – Simple program example to update value in map. To update an existing value in the map, first we will find the value with the given key using map::find() function. If the key exists, then will update it with new value.
In Simple Associative Containers, where the elements are the keys, the elements are completely immutable; the nested types iterator and const_iterator are therefore the same. Other types of associative containers, however, do have mutable elements, and do provide iterators through which elements can be modified.
In computing, associative containers refer to a group of class templates in the standard library of the C++ programming language that implement ordered associative arrays. Being templates, they can be used to store arbitrary elements, such as integers or custom classes.
This injects Undefined Behavior in your program if you modify the values in a way that the comparison of any two keys is different after the change according to the comparator you specified.
Per Paragraph 23.2.4/3 of the C++11 Standard ([associative.reqmts]):
The phrase “equivalence of keys” means the equivalence relation imposed by the comparison and not the
operator==
on keys. That is, two keysk1
andk2
are considered to be equivalent if for the comparison objectcomp
,comp(k1, k2) == false && comp(k2, k1) == false
. For any two keysk1
andk2
in the same container, callingcomp(k1, k2)
shall always return the same value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With