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.
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.
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.
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.