Oli*_*ock 7 c++ const-correctness
我得到了
Error C2678 binary '*': no operator found which takes a left-hand operand of type 'const _InIt' (or there is no acceptable conversion)
Run Code Online (Sandbox Code Playgroud)
它是由 MSVC (2022, V17.1) 标头中的代码抛出的<algorithm>。
Error C2678 binary '*': no operator found which takes a left-hand operand of type 'const _InIt' (or there is no acceptable conversion)
Run Code Online (Sandbox Code Playgroud)
const由于上面一行的原因,第二行抛出了错误。
我传入的迭代器是“平面文件”上的自定义 LegacyRandomAccessIterator,它operator*看起来像这样:
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
Run Code Online (Sandbox Code Playgroud)
换句话说,我不能只是将我的标记operator*为const,因为它不是,也不可能是真的 - 它正在从磁盘加载一组缓冲的记录,而这不是const当前设计中的操作。
我实现了一个“虚拟”const版本来证明这就是问题所在:
value_type operator*() { return current(); }
...
ValueType current() {
if (!cur_valid_) {
cur_ = ffdb_->get_record(pos_);
cur_valid_ = true;
}
return cur_;
}
Run Code Online (Sandbox Code Playgroud)
错误消失了,但显然这没有任何作用。
libstdc++ 没有对const operator*. (我没有测试过libc++)
无需对迭代器进行重大重新设计,这个问题是否可以解决?
MSVC的实现有这样的期望合理吗?
std::lower_bound接受一个Cpp17ForwardIterator,它也必须是一个Cpp17InputIterator。Cpp17InputIterator要求包括 :
| 表达 | 返回类型 |
|---|---|
*a |
reference,可转换为T |
这里,a是“ or类型的值”Xconst X,因此 MSVC 需要 const 限定的一元间接运算符是合理的;“或”意味着使用迭代器的代码可以使用其中一个,并且迭代器的作者必须支持两者。(请注意,Cpp17InputIterator与Cpp17OutputIterator不同,其中所需的操作是*r = o,带有r非常量引用 。X&)
所以你operator*应该有const资格,并返回推荐信;T具体来说,是对or的引用const T(这是Cpp17ForwardIterator 的要求)。您可以using reference = const T&通过制作cur_ 和 来直接满足这一点cur_valid_ mutable。
此处的使用mutable是完全合法的;由于operator*() const是幂等的,因此它是“逻辑常量”,并且对数据成员的修改是不可观察的。
| 归档时间: |
|
| 查看次数: |
221 次 |
| 最近记录: |