【问题标题】:accessing private member in public const method在公共 const 方法中访问私有成员
【发布时间】:2013-10-24 16:19:06
【问题描述】:

我有以下 C++ 类和方法。我正在尝试从 const 函数numOutgoing() 中访问私有成员“传出”。我对第 127-128 行与第 129-130 行的行为感到困惑。

第 129 行:制作一个副本,以后可以修改,const 函数不关心 第 130 行:获取引用,但 vec 被定义为 const,所以一切正常。

第 127 行:我假设正在制作副本,但出现编译器错误 第 128 行:相同的编译器错误。

 90 class Graph
 91 {
 92         map<int, vector<int> > outgoing;
 93
 95   public:
 96         Graph(const vector<int> &starts, const vector<int> &ends);
 97         int numOutgoing(const int nodeID) const;
 99 };
100
120
121 int
122 Graph::numOutgoing(const int nodeID) const
123 {
124         if (outgoing.find(nodeID) == outgoing.end()) {
125                 throw invalid_argument("Invalid node Id");
126         }
127         // vector<int> vec = outgoing[nodeID];
128         // const vector<int> &vec = outgoing[nodeID];
129         vector<int> vec = outgoing.at(nodeID);
130         // const vector<int> &vec = outgoing.at(nodeID);
131
132         return vec.size();
133 }

我试图理解为什么第 127 / 128 行给我以下编译错误:

./templ.cc:128:42: error: passing 'const std::map<int, std::vector<int> >' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = std::vector<int>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::vector<int> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::vector<int>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]' discards qualifiers [-fpermissive]

以下是“map”类中 operator[] 和 at 方法的原型。

      mapped_type& operator[] (const key_type& k);  <======
      mapped_type& operator[] (key_type&& k);

      mapped_type& at (const key_type& k);
const mapped_type& at (const key_type& k) const;

如果有人能帮助我理解编译错误,我将不胜感激。问题可能是operator[] 没有返回const 类型吗?如果是这样,那么operator[]at 是不等价的,对吧?

【问题讨论】:

    标签: c++ c++11 map stl


    【解决方案1】:

    这是因为方法

    int Graph::numOutgoing(const int nodeID) const
    

    const,而 operator[] 不是 const。这是因为一个设计决定:如果尝试访问operator[] 不存在的密钥,则会创建它,从而修改std::map

    要解决您的问题,请使用map&lt;int, vector&lt;int&gt; &gt;::const_iterator result = outgoing.find(nodeID); 然后,如果它不在end(),您可以简单地使用result-&gt;first 访问键和result-&gt;second 的值。

    【讨论】:

    • 如果他可以使用 C++11,std::map::at() 函数也可以工作,但是如果找不到项目,它会抛出,所以你需要一个 try-catch 块。跨度>
    【解决方案2】:

    您的问题是,由于您的 numOutgoing 函数是 const,所以它只能在类成员上调用 const 函数。在这种情况下,只有const mapped_type&amp; at (const key_type&amp; k) const; 是有效的。

    您还可以将 const_iterator 保留在 outgoing.find(nodeID) 中并取消引用以获取对子向量的 const 访问权限。

    【讨论】:

      【解决方案3】:

      如果有人能帮助我理解编译错误,我将不胜感激。问题可能是“operator []”不返回“const”类型吗?如果是这样,那么“operator[]”和“at”就不等价了,对吧?

      是的,operator[]at 根本不等价。

      at 只会返回一个值,因此它可以是const。如果不存在这样的元素,则会抛出 std::out_of_range 类型的异常。

      operator[] 另一方面,如果不存在任何元素,它永远不会抱怨,因为它会尝试创建一个新元素。选择此行为是为了:

      std::map<int, int> x;
      x[0] = 1;
      

      是可能的。

      【讨论】:

        【解决方案4】:

        问题是非常量的运算符 []。调用者可以使用它返回的非 const 引用来修改映射内容,因此该运算符不会被标记为 const。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-06
          • 1970-01-01
          • 2014-12-12
          相关资源
          最近更新 更多