常量正确性对于Getter函数的影响

5

以下是关于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以常量引用的方式传递,因为我调用了非常量成员的getter函数。就其签名而言,这给人的印象是operator()会修改foo。
我应该纠正这个问题吗?如果是,怎么做?
2个回答

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

2

常量正确性适用于您执行方法的对象。因此:

bool operator()(Foo& foo) const

意思是operator()不会更改函数对象类中的任何内容,比如_memberName(它似乎是函数对象类的成员)。
按照定义方式,允许更改Foo(调用非const方法)。 编辑: 请参阅Mike Seymour的答案,因为它描述了一种修复方法。我个人经常这样做,但似乎没有完全理解您的问题。 :)

但问题是,我们能否安排通过const引用传递foo - Mike Seymour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接