Перегружается const: std :: map :: find () const overload - PullRequest
5 голосов
/ 01 мая 2011

Рассмотрим следующий фрагмент:

#include <map>

class C {
public:
    C() {}

    const int& f(const int& x) const
    {
        // Error: cannot cast const int* to int* const
        return myMap.find(&x)->second;

        // With a const_cast works:
        //return myMap.find(const_cast<int* const>(&x))->second;
    }

    std::map<int*, int> myMap;
};

int _tmain(int argc, _TCHAR* argv[])
{
    int x = 0;

    C c;
    c.f(x);

    return 0;
}

Ошибка в f() вызвана константной перегрузкой find() карты, принимающей const KeyType&. Поскольку тип ключа карты int*, это превращается в int* const. f() принимает параметр const int&, который является правильным, поскольку параметр никогда не изменяется.

К сожалению, это заканчивается попыткой привести const int* к int* const, который теряет квалификатор const в int и не компилируется.

Это немного раздражает, потому что параметр определенно никогда не изменяется - он просто используется для поиска () - но мне все еще нужно const_cast.

Есть ли способ написать f() без const_cast?

Ответы [ 2 ]

7 голосов
/ 01 мая 2011

Вы можете просто изменить тип map на std::map<const int*, int>;Я спрашиваю, нужны ли вам в первую очередь указатели в качестве ключей.Как указывает Джеймс, тип ключа должен быть const int*, потому что вы никогда не собираетесь изменять референт через map.Если бы ты это сделал, я бы еще больше волновался.

5 голосов
/ 01 мая 2011

Реальный вопрос: почему индекс карты не является указателем на const?(Предположим, конечно, что это должен быть указатель.) Вы действительно хотите иметь возможность изменять индекс с помощью чего-то вроде *myMap.find(&x)->first = xxx;Я бы сказал, что это довольно необычно, учитывая, что у вас уже есть указатель на объект.

...