簡體   English   中英

msvc std::lower_bound 需要 const 運算符*

[英]msvc std::lower_bound requires const operator*

我得到一個

Error   C2678   binary '*': no operator found which takes a left-hand operand of type 'const _InIt' (or there is no acceptable conversion)

它由 MSVC (2022, V17.1) <algorithm> header 中的這段代碼拋出。

template <class _FwdIt, class _Ty, class _Pr>
_NODISCARD _CONSTEXPR20 _FwdIt lower_bound(_FwdIt _First, const _FwdIt _Last, const _Ty& _Val, _Pr _Pred) {

...
        const auto _UMid                   = _STD next(_UFirst, _Count2);
        if (_Pred(*_UMid, _Val)) { // try top half

第二行由於上面一行的const而拋出錯誤。

我傳入的迭代器是一個基於“平面文件”的自定義 LegacyRandomAccessIterator,它的operator*如下所示:

  value_type operator*() { return current(); }

...

  ValueType current() {
    if (!cur_valid_) {
      cur_       = ffdb_->get_record(pos_);
      cur_valid_ = true;
    }
    return cur_;
  }

換句話說,我不能只將我的operator*標記為const ,因為它不是,也不可能是——它正在從磁盤加載一組緩沖記錄,而這不是當前設計中的const操作。

我實現了一個“虛擬” const版本來證明這是問題所在:

 value_type operator*() const { return value_type{}; }

錯誤消失了,但顯然這沒有做任何事情。

libstdc++ 沒有對const operator*的這種期望。 (我還沒有測試過 libc++)

如果不對我的迭代器進行一些重大的重新設計,這是可以解決的嗎?

MSVC的實現有這個期望合理嗎?

std::lower_bound采用Cpp17ForwardIterator ,它也必須是Cpp17InputIterator Cpp17InputIterator 要求包括

表達 返回類型
*a reference ,可轉換為T

在這里, a“類型Xconst X的值” ,因此 MSVC 有理由要求 const 限定的一元間接運算符; “或”意味着使用迭代器的代碼可以使用其中一個,迭代器的作者必須支持兩者。 (請注意, Cpp17InputIterator不同於Cpp17OutputIterator ,其中所需的操作是*r = o ,其中r是非常量引用X& 。)

所以你的operator*應該有const資格,並返回一個引用; 具體來說,是對Tconst T的引用(這是Cpp17ForwardIterator的要求)。 您可以通過using reference = const T&並使cur_cur_valid_ mutable來直接滿足這一點。

在這里使用mutable是完全合法的; 由於operator*() const是冪等的,因此它是“邏輯上的 const”,並且對數據成員的修改是不可觀察的。

暫無
暫無

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

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