Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not modify key of associative container?

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?

like image 444
Daniel Frey Avatar asked Mar 29 '13 10:03

Daniel Frey


People also ask

Why is std set an associative container?

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.

Can I update key in map C++?

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.

Do associative containers provide iterators?

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.

What is meant by associative container?

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.


1 Answers

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 keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false. For any two keys k1 and k2 in the same container, calling comp(k1, k2) shall always return the same value.

like image 180
Andy Prowl Avatar answered Nov 06 '22 04:11

Andy Prowl