【问题标题】:Const Correctness for Getter FunctionGetter 函数的常量正确性
【发布时间】:2012-09-14 14:07:19
【问题描述】:

这是一个关于 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);

这里让我感到困惑的是,我不能通过引用 const 来传递 Foo,因为我正在调用非 const 成员 getter 函数。关于它的签名,这给人的印象是 operator() 改变了 foo。

我应该纠正这个问题吗?如果是,如何纠正?

【问题讨论】:

    标签: c++


    【解决方案1】:

    通常的做法是为成员函数添加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】:

      const 正确性适用于您执行其方法的对象。所以:

      bool operator()(Foo& foo) const
      

      意味着operator() 不会改变函子类中的任何内容,例如_memberName(它似乎是函子类的成员)。

      它的定义方式,允许改变Foo(调用非常量方法)。

      编辑: 请参阅Mike Seymour 的答案,因为它描述了一种解决方法。我个人做了很多,但似乎没有完全得到你的问题。 :)

      【讨论】:

      • 但问题是,我们可以安排通过const 参考传递foo 吗?
      猜你喜欢
      • 1970-01-01
      • 2013-07-02
      • 2021-04-24
      • 1970-01-01
      • 1970-01-01
      • 2010-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多