2012-09-14 15 views
5

Aquí hay una pregunta simple sobre const correctness.Const Corrección para Getter Función

tengo esta clase:

template <class T> 
class Foo 
{ 
public: 
    std::map<std::string, boost::any> members; 

    template <typename T> 
    std::vector<T>& member(const std::string& memberName) 
    { 
     return boost::any_cast<std::vector<T>&>(members[memberName]); 
    } 
}; 

entonces tengo un funtor que incluye lo siguiente:

bool operator()(Foo& foo) const 
{ 
    std::vector<T> & member = foo.member<T>(_memberName); 

Lo que me confunde es que no puedo pasar Foo por referencia a const, ya que Estoy llamando a la función getter no miembro. Con respecto a su firma, esto da la impresión de que operator() cambia foo.

¿Debo corregir esto y, en caso afirmativo, cómo?

Respuesta

9

La forma más habitual es añadir una sobrecarga const para la función de miembro:

template <typename T> 
std::vector<T> const & member(const std::string& memberName) const 
{    ^^^^^           ^^^^^ 
    return boost::any_cast<std::vector<T> const &>(members.at(memberName)); 
}           ^^^^^   ^^ 

Llamando el miembro en un const Foo elegirá esta sobrecarga; llamándolo en un const elegirá el original.

Tenga en cuenta que at() es una adición relativamente nueva a std::map. Si le pegan con una biblioteca obsoleta, necesitará algo como:

std::map<std::string, boost::any>::const_iterator found = members.find(memberName); 
if (found == members.end()) { 
    throw std::runtime_error("Couldn't find " + memberName); 
} 
return boost::any_cast<std::vector<T> const &>(found->second); 
2

La corrección const se aplica sobre el objeto, cuyo método se ejecuta. Por lo tanto:

bool operator()(Foo& foo) const 

significa que operator() no va a cambiar nada en la clase funtor, como el _memberName (que parece ser un miembro de la clase funtor).

La forma en que se define, está permitido cambiar Foo (llamar a métodos no const).

EDITAR: respuesta Ver Mike Seymour 's, ya que describe una forma de solucionarlo. Personalmente, he hecho mucho pero parece que no recibí exactamente su pregunta. :)

+0

Pero la pregunta es, ¿podemos organizar pasar 'foo' por' referencia const'? –

Cuestiones relacionadas