C ++使用const函数中的映射调用指向成员的指针

时间:2012-02-09 11:19:47

标签: c++ pointers map std member

我有一个指向成员的指针映射声明为:

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 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

只需使op_add成为const成员函数。

 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,正如R. Martinho Fernandes正确指出的那样。

答案 2 :(得分:0)

如果你知道自己在做什么,你可以尝试使用c ++标志编译-fpermissive,就像G ++所说的那样。