簡體   English   中英

在非常量函數中使用const_iterator

[英]Using const_iterator in non constant function

我有一個結構類似的程序:

class A {
    private:
        std::set<B> members;
    public:
        void func(const C& arg) {
            std::set<B>::iterator iter = members.find(a);
            if(iter != members.end()) {
                iter->check(arg);
            }
        }
}



class B {
    private:
        std::deque<C> writers;
    public:
        void check(const C& arg) {
            if(std::find(writers.begin(), writers.end, arg) != writers.end()) {
                /* Code */
            }
        }
}


class C {
  private:
      int id;
  public:
      bool operator==(const C& arg) {
          return arg.id == this->id;
      }
}

編譯此文件時,收到以下錯誤消息:

no matching function for call to ‘B::check(const C&) const’  
note: candidates are: void B::check(const C&) <near match>

如果我將check()聲明為const則編譯器將引發錯誤,要求將C類中重載的運算符==聲明為const 我不知道將重載運算符設為const是否正確。 (我嘗試過一次,據我所知它也給出了一些錯誤)。

我嘗試解決此問題已超過五天,但仍然沒有線索。

首先是operator== 應該const 除非您想使用戶感到困惑,否則它不會修改數據,也永遠不會修改數據。 通常,每個不需要修改對象狀態的函數都應為const ,以提供最大的靈活性(即允許通過常量引用進行調用)。

同樣可以應用於B::check ,如果它僅測試而不是修改,則應為const 並且通過擴展A::func ,如果不需要修改,則應為const。

在不同的編譯器中,錯誤消息將有所不同。 在您的情況下,編譯器執行重載解析,但未找到與其匹配的調用,這是它抱怨的內容:

沒有匹配的函數來調用'B :: check(const C&)const'
注意:候選者為:void B :: check(const C&)

這表明它看到了您的成員,但由於需要帶有const標簽的成員函數而將其丟棄。 在其他編譯器中,錯誤消息將包含以下內容: 調用void B::check(const C&)丟棄限定符 ,這更加令人費解,並試圖說在const引用上調用非const成員函數將需要忽略const限定詞。

您必須將B::check()C::operator==const因為它們在對象狀態下不做任何更改。

也可能不是那么明顯,但是std::set<B>::iterator實際上是const_iterator (假設您使用的是C ++ 11編譯器)! 因此,您無法通過set迭代器從B對象調用任何非const函數成員。

請記住,在可能的情況下,您應該首選非const版本。 至少這就是斯科伯·梅伯所說的。

這是一個漫長的討論:

我應該使用迭代器而不是const_iterators嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM