这是一个关于const正确性的简单问题。
我有这堂课:
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]);
}
};
然后我有一个包含以下内容的仿函数:
bool operator()(Foo& foo) const
{
std::vector<T> & member = foo.member<T>(_memberName);
让我感到困惑的是,我无法通过引用传递Foo,因为我正在调用非const成员getter函数。关于它的签名,这给人的印象是operator()改变了foo。
我应该纠正这个问题,如果是这样的话?
答案 0 :(得分:9)
通常的方法是为成员函数添加const
重载:
template <typename T>
std::vector<T> const & member(const std::string& memberName) const
{ ^^^^^ ^^^^^
return boost::any_cast<std::vector<T> const &>(members.at(memberName));
} ^^^^^ ^^
在const Foo
上调用该成员将选择此重载;在非const
上调用它
会选择原来的。
请注意,at()
是std::map
的新增内容。如果您遇到过时的库,则需要以下内容:
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);
答案 1 :(得分:2)
const正确性适用于您执行其方法的对象。所以:
bool operator()(Foo& foo) const
表示operator()
不会更改仿函数类中的任何内容,例如_memberName
(似乎是仿函数类的成员)。
定义它的方式,允许改变Foo(调用非const方法)。
修改强>: 请参阅Mike Seymour的答案,因为它描述了修复它的方法。我个人已经做了很多,但似乎没有得到你的问题。 :)