2012-09-14 15 views
5

Oto proste pytanie dotyczące poprawności stałej.Poprawność Const dla funkcji Gettera

mam tej klasy:

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

Mam następnie funktor, który obejmuje następujące elementy:

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

Co myli mi o to, że nie mogę przejść Foo przez odniesienie do const, bo "Wywołuję funkcję pobierającą non const member. W odniesieniu do podpisu wywołuje to wrażenie, że operator() zmienia się w foo.

Czy powinienem to poprawić, a jeśli tak, to w jaki sposób?

Odpowiedz

9

Zwykłym sposobem jest dodanie przeciążenie const dla funkcji członka:

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

Wywołanie członka na const Foo wybiorą tę przeciążenia; Wywołanie go na non-const wybierze oryginalny.

Należy pamiętać, że at() jest całkiem nowym dodatkiem do std::map. Jeśli utkniesz w nieaktualnej bibliotece, potrzebujesz czegoś w rodzaju:

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

Poprawność stałości dotyczy obiektu, którego metodę wykonujesz. Więc:

bool operator()(Foo& foo) const 

oznacza, że ​​nie będzie nic operator() w klasie funktora, podobnie jak _memberName (co wydaje się być członkiem klasy funktora) zmienić.

Sposób, w jaki jest zdefiniowany, może zmieniać Foo (wywoływać metody niestałe).

EDIT: odpowiedź See Mike Seymour „s jak to opisuje drogę, aby go naprawić. Osobiście zrobiłem to bardzo często, ale wydawało mi się, że nie dostaję dokładnie tego pytania. :)

+0

Ale pytanie brzmi, czy możemy zorganizować przekazanie 'foo' przez referencję' const'? –

Powiązane problemy