C++ Вызов указателя на член с картой из функции const
У меня есть карта указателя на член, объявленный как:
std::map<char, T (Operand::*)(const T &, const T &)> op_map;
Я заполняю свою карту указателем на член прямо в конструкторе моего класса с помощью:
op_map['+'] = &Operand::op_add;
Например, исходный код op_add:
T op_add(const T & a, const T & b) {
return a + b;
}
И я хочу вызвать мой указатель на член из функции const. Вот исходный код:
IOperand *res_int32(char op, const IOperand & rhs) const {
IOperand *res = const_cast<IOperand *>(&rhs);
Operand<int> *tmp = dynamic_cast<Operand<int>*>(res);
T res_calc = (this->*op_map[op])(_value, (T)tmp->getValue());
}
Но это всегда делает меня ошибкой:
Operand.hpp:70:64: error: passing ‘const std::map<char, double (Operand<double>::*)(const double&, const double&), std::less<char>, std::allocator<std::pair<const char, double (Operand<double>::*)(const double&, const double&)> > >’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = char, _Tp = double (Operand<double>::*)(const double&, const double&), _Compare = std::less<char>, _Alloc = std::allocator<std::pair<const char, double (Operand<double>::*)(const double&, const double&)> >, std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = double (Operand<double>::*)(const double&, const double&), std::map<_Key, _Tp, _Compare, _Alloc>::key_type = char]’ discards qualifiers [-fpermissive]
Operand.hpp:70:64: error: invalid conversion from ‘const Operand<double>* const’ to ‘Operand<double>*’ [-fpermissive]
У вас есть какое-нибудь решение?
Спасибо.
3 ответа
operator[]
не может быть применен к const
карта, так как он вставляет новый элемент, если ключ не найден.
В C++11 есть at
функция, которая выдает исключение, если ключ не найден:
T res_calc = (this->*op_map.at(op))(_value, (T)tmp->getValue());
^^^^^^^
В C++03 вам нужно будет использовать find
:
map_type::const_iterator found = op_map.find(op);
if (found != op_map.end()) {
T res_calc = (this->*(found->second))(_value, (T)tmp->getValue());
} else {
// handle error
}
Вам также необходимо изменить тип функций-членов на карте на
T (Operand::*)(const T &, const T &) const
^^^^^
чтобы призвать их this
из const
функция-член.
Просто сделайте op_add константной функцией-членом.
T op_add(const T & a, const T & b) const // <<<
{
return a + b;
}
И вместо std::map::operator[] используйте std:: map:: find http://www.cplusplus.com/reference/stl/map/find/
РЕДАКТИРОВАТЬ:
Вам также нужно изменить тип карты на std::map<char, T (Operand::*)(const T &, const T &) const> op_map
, как правильно указал Р. Мартиньо Фернандес.
Если вы знаете, что делаете, вы можете попробовать скомпилировать с флагом C++ -fpermissive, как сказал G++.