2012-02-09 1 views
0

J'ai une carte de pointeur à un membre déclaré comme:C++ Appel pointeur vers un membre d'une carte d'une fonction const

std::map<char, T (Operand::*)(const T &, const T &)> op_map; 

Je remplirai ma carte avec pointeur vers un membre directement dans le constructeur de ma classe avec:

op_map['+'] = &Operand::op_add; 

Par exemple, le code source est op_add:

T op_add(const T & a, const T & b) { 
    return a + b; 
    } 

Et je veux appeler mon pointeur vers Membe r d'une fonction const. Voici le code source:

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()); 
    } 

Mais il me fait toujours une erreur:

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] 

Avez-vous une solution?

Merci.

+0

L'opérateur '[operator] d'une carte ne peut pas être appelé sur des cartes' const'. –

+0

Pourquoi diable avez-vous besoin de 'const_cast'? Est-ce que 'l'opérande :: getValue' n'est pas déclaré' const'? –

Répondre

2

operator[] ne peut pas être appliqué à une carte const, car il insère un nouvel élément si la clé n'est pas trouvée.

En C++ 11, il y a une fonction at qui jette une exception si la clé est introuvable:

T res_calc = (this->*op_map.at(op))(_value, (T)tmp->getValue()); 
          ^^^^^^^ 

En C++ 03, vous devez utiliser 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 
} 

Vous aurez également besoin de changer le type des fonctions membres dans la carte à

T (Operand::*)(const T &, const T &) const 
            ^^^^^ 

pour les appeler au this à partir d'une fonction de membre const.

0

Si vous savez ce que vous faites, vous pouvez essayer de compiler avec le drapeau C++ -fpermissive comme dit G ++.

+2

Si vous savez ce que vous faites, alors vous saurez que c'est une très mauvaise idée. –

+2

Non, s'il vous plaît. '-fpermissive' permet beaucoup trop de choses que vous ne voulez jamais activer. C'est * trop permissif *. Et vous pouvez toujours résoudre le problème avec une * solution réelle * sans avoir besoin de '-fpermissive'. –

1

Faites simplement d'op_add une fonction membre const.

T op_add(const T & a, const T & b) const // <<< 
{ 
    return a + b; 
} 

Et au lieu de std :: carte :: operator [] utilisation std :: carte :: find http://www.cplusplus.com/reference/stl/map/find/

EDIT:

Vous devez également modifier le type de carte à std::map<char, T (Operand::*)(const T &, const T &) const> op_map, comme le souligne justement R. Martinho Fernandes.

+0

Et changer la carte en 'std :: map op_map'. –

+0

Cela ne fonctionne pas, a toujours une erreur de compilation. http: // pastebin.com/rCbZrss7 –

+0

@jeffrey, utilisez map :: find au lieu de map :: operator [] – Gigi

Questions connexes