#c #stl #map #const-correctness
#c #stl #словарь #const-корректность
Вопрос:
Рассмотрим следующий фрагмент:
#include <map>
class C {
public:
C() {}
const intamp; f(const intamp; x) const
{
// Error: cannot cast const int* to int* const
return myMap.find(amp;x)->second;
// With a const_cast works:
//return myMap.find(const_cast<int* const>(amp;x))->second;
}
std::map<int*, int> myMap;
};
int _tmain(int argc, _TCHAR* argv[])
{
int x = 0;
C c;
c.f(x);
return 0;
}
Ошибка в f()
вызвана постоянной перегрузкой map, find()
принимающей const KeyTypeamp;
значение. Поскольку ключевым типом карты является int*
, это превращается в int* const
. f()
принимает const intamp;
параметр, который является правильным, потому что параметр никогда не изменяется.
К сожалению, это заканчивается попыткой привести a const int*
к a int* const
, что приводит к потере спецификатора const в int и не будет компилироваться.
Это немного раздражает, потому что параметр определенно никогда не изменяется — он просто используется для find() — но мне все еще нужно const_cast
это.
Есть ли способ написать f()
без const_cast
?
Комментарии:
1. Это довольно необычно: почему вы используете указатели в качестве ключей карты?
2. В моих приложениях ключи должны быть ссылками на объекты с большим весом, и вы не можете использовать ссылку в качестве ключа карты.
Ответ №1:
Вы можете просто изменить тип map
на std::map<const int*, int>
; Однако я сомневаюсь, нужны ли вам указатели в качестве ключей в первую очередь. Как указывает Джеймс, тип ключа должен быть const int*
, потому что вы никогда не собираетесь изменять референт с помощью map
. Если бы вы это сделали, я бы волновался еще больше.
Ответ №2:
Реальный вопрос в том, почему индекс карты не является указателем на const? (Предполагая, конечно, что это должен быть указатель.) Вы действительно хотите иметь возможность изменять индекс с помощью чего-то вроде *myMap.find(amp;x)->first = xxx
; Я бы сказал, что это довольно необычно, учитывая, что у вас уже есть указатель на объект.