Is it possible to introduce a <Key, Value> pair into a <const Key, Value> pair?

So, I have an intelligent iterator that emulates a map const_iterator, and it needs to inline the return type inside. Obviously, I would like to keep pair<Key, Value> in my iterator class (since I need to change it), but at the same time, I would like dereferencing functions to display pair<const Key, Value> (actually this would be const pair<const Key, Value>& and const pair<const Key, Value>* respectively). The only solution I came up with is to dynamically allocate a new pair every time, changing the value that my iterator class points to changes. Needless to say, this is a bad decision.

I also tried *const_cast<const pair<const Key, Value> >(&value) , where value declared as pair<Key, Value> .

Any help would be greatly appreciated (as well as knowing that this is not possible).

EDIT

For the curious: I ended up storing pair<const Key, Value> p in my iterator class. To change a pair, I change the two elements separately based on the base iterator ( map<Key, Value>::const_iterator it ), const_cast with the key so that it can be changed, for example:

 *const_cast<Key*>(&p.first) = it->first; p.second = it->second; 

Not a solution that I'm very happy with, but it does its job, and the casting methods are happy because I am storing something of the kind that they can reference.

+4
source share
4 answers

You can convert a value of type pair<Key,Value> to pair<const Key,Value> .

However, after carefully reading the question, you are really asking if using pair<Key,Value> create a pointer or link to pair<const Key,Value> , referring to the same object.

The answer is not the only situation where a link or a pointer to one type can refer to an object of another type, if the type of the object is inherited from the reference type.

One possibility is to return a pair of links pair<const Key&, Value&> created from the pair you want to link.

+6
source

Yes.

 std::pair<int, double> p(1,2); std::pair<const int, double> q = p; // no problem //q.first = 8; // error q.second = 9; int b; double d; std::pair<int &, double &> s(b,d); std::pair<int const &, double &> t = s; // also fine 
+5
source

As pointed out by Kerrek SB, you can build std::pair<const Key, Value> from std::pair<Key, Value> . However, your original question implies that you want to avoid creating std :: pair objects every time your iterator is dereferenced.

Unfortunately, there is no good way to do this. You may need to create a paired object and actually save it somewhere, especially for the operator->. Otherwise, you should be able to store pair<const Key, Value> on your map in order to be able to return links / pointers to it from your iterator. Basically, in order to return a link / pointer, it must be stored somewhere in this form: it cannot be temporary.

Avoid const_cast. It just asks for undefined behavior when you use it to create a pair in this way, even if it can work quite often.

+2
source

I met exactly the same problem. My solution was to create a new map object as part of the iterator class, and then add to it the members that are missing in the upper class of the map and return a link to its members. Not very effective, but it works.

Your solution has two problems:

  • Assigning a constant variable with const_cast is undefined behavior. Compiler optimization can provide strange results.
  • Any new dereferencing will invalidate the results of the previous dereferencing. It should not. Thus, depending on the use of your iterator, this can also cause strange results.
0
source

Source: https://habr.com/ru/post/1383556/


All Articles