Недавно я столкнулся с проблемой, и единственный способ избежать этого - использовать const_cast - но я предполагаю, что есть способ, которым я не думаю об этом, не изменяя при этом функции кода. Приведенный ниже фрагмент кода превращает мою проблему в очень простой пример.
struct Nu
{
Nu() {v = rand();}
int v;
};
struct G
{
~G()
{
for(auto it = _m.begin(); it != _m.end(); it++) delete it->first;
}
void AddNewNu()
{
_m[new Nu] = 0.5f;
}
void ModifyAllNu()
{
for(auto it = _m.begin(); it != _m.end(); it++) it->first->v++;
}
float F(const Nu *n) const
{
auto it = _m.find(n);
// maybe do other stuff with it
return it->second;
}
map<Nu*, float> _m;
};
Здесь предположим, что Nu на самом деле является очень большой структурой, макет которой уже зафиксирован необходимостью сопоставления с внешней библиотекой (и, таким образом, «float» не может быть просто свернут в Nu, и по различным другим причинам он может ' t быть map<Nu, float>
). Структура G имеет карту, которая используется для хранения всех созданных им Nu (и, в конечном счете, для удаления их всех при уничтожении). Как написано, функция F не будет компилироваться - она не может привести (const Nu * n) к (Nu n), как ожидается std :: map. Однако карта не может быть переключена на map<const Nu*, float>
, потому что некоторые неконстантные функции все еще должны изменить Nu внутри _m. Конечно, я мог бы альтернативно сохранить все эти Nu в дополнительном std :: vector и затем переключить тип карты на const - но это вводит вектор, который должен быть совершенно ненужным. Поэтому единственная альтернатива, о которой я подумал в данный момент, - это использовать const_cast внутри функции F (которая должна быть безопасной const_cast), и мне интересно, можно ли этого избежать.
После еще большей охоты эта точно такая же проблема уже решена здесь: Вызов карты :: find с аргументом const