Вот этот простой код
#include <map>
class MyMap : public std::multimap<int*, int*>
{
public:
void foo(const int* bar) const
{
equal_range(bar);
}
};int main()
{
MyMap myMap;
int number;
myMap.foo(&number);
return 0;
}
Он не компилируется и выдает следующую ошибку
error C2663: 'std::_Tree<_Traits>::equal_range' : 2 overloads have no legal conversion for 'this' pointer
Я видел много тем об этой ошибке, и кажется, что это const
вопрос. Это хорошо, если я включаю foo(const int* bar)
в foo(int* bar)
,
Проблема в том, что я не понимаю, как foo
контент должен изменить что-либо на мой объект MyMap. std::multimap
предлагает постоянную версию equal_range
:
http://www.cplusplus.com/reference/map/multimap/equal_range/
В чем моя проблема?
Спасибо
Проверьте определение equal_range:
pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
Ожидается постоянная ссылка на key_type
: const key_type& k
,
То, что вы пытались указать, было указателем на постоянное целое число: const int* bar
Почему это не работает, хотя оба значения const
?
const int& foo
означает, что вы не можете позволить foo
ссылаются на другое целое число, но разрешено изменять значение указанного целого числа.const int* foo
означает, что вы можете позволить foo
указывает на другое целое число, но вы не можете изменить значение целого числа, на которое оно указывает.На самом деле карта ожидает const int*& k
, но карта автоматически преобразует это, если вы предоставите int*
только (без const
).
Также обратите внимание, что MyMap
объект по-прежнему не может быть изменен вашим foo
функционировать, даже если вы измените const int*
в int*
как еще есть еще один конст в конце вашего foo
функция. Это const в самом конце объявляет функцию как постоянную, что означает, что она не может изменить текущий объект, в котором она выполняется. Если он пытается изменить его или вызвать что-либо, что может его изменить, вы получите ошибку компилятора. (Отказ от ответственности: в любом случае есть способы изменить класс внутри const-функции, но это уже другая тема.)
Если факт, правильное сообщение компилятора может дать вам ответ. Для одной из двух перегрузок ( const
один):
/usr/local/include/c++/v1/map:1836:41: note: candidate function not viable: 1st argument ('const int *')
would lose const qualifier
const int*
это указатель на const int
, Метод ожидает const key_type&
т.е. const int*&
аргумент, что это const
ссылка на (неconst
) int*
,
Когда запутался, предпочитаю писать const int*
как int const*
, что одно и то же. Тогда вы увидите разницу const int*&
более четко.
Чтобы ваш код работал, используйте int*
вместо const int*
,
Я считаю, что проблема связана с несоответствием на key_type
,
С одной стороны у вас есть мультикарта, где key_type=int*
в то время как с другой стороны вы передаете key_type=const int*
таким образом, пытаясь сбросить константный квалификатор на key_type
, Я был смущен этим тоже, потому что я расширял key_type
на мой взгляд, чтобы получить const int*&
который должен быть совместимым. Однако несоответствие происходит раньше на key_type
сам. По крайней мере, это единственное логическое объяснение, которое я мог придумать.
Мое предложение было бы сделать key_type
const int*
и оставьте свой параметр функции как есть. В конце концов, зачем вам указатель на изменяемое значение в качестве ключа к карте?