【问题标题】:Why doesn't const range based for use const_iterator?为什么不使用基于 const 范围的 const_iterator?
【发布时间】:2014-10-24 19:05:57
【问题描述】:

如果我只想按对象公开一个 const 迭代器:

class MyList
{
  public:
    const_iterator begin() const;
    const_iterator end() const;
  private:
    iterator begin();
    iterator end();
};

看来我应该能够使用基于范围的 const 版本:

MyList list;
...
for(const auto & value : list)
{
}

编译器抱怨beginend 是私有的。为什么不使用const_iterator 版本?

【问题讨论】:

  • template <class T> T const& as_const(T const& t) { return t; }....for (auto& value : as_const(list)) ...
  • 这是一个对用户不友好的设计,因为你不能再做MyList list; list.begin();。考虑将私有非常量版本重命名为其他版本。
  • 我同意,但这只是对用户不友好,因为编译器拒绝找到 begin/end 的 const 版本。

标签: c++ c++11 iterator constants auto


【解决方案1】:

在访问检查之前完成重载解析,以避免仅仅通过更改访问说明符就神奇地破坏代码。

表达式(它的类型)之后发生的事情被忽略了。如果需要,编译器会在之后尝试找到一个有效且明确的转换序列。

因此,非const 对象的beginend 被选中,然后编译器偶然发现了那个大private 符号。

【讨论】:

  • 但是为什么编译器看不到const auto & 并意识到它应该使用const_iterator 版本(恰好是公开的)?
  • 编译器永远不会根据您使用结果的位置进行重载解析。之后它会尝试找到一个有效的转换序列。
  • 有时结果会返回到重载决议(例如static_casting 重载函数的名称),但这不是少数上下文之一,无论如何访问控制在重载决议之后发生。
猜你喜欢
  • 2016-04-03
  • 1970-01-01
  • 2020-04-03
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 1970-01-01
  • 2021-04-29
相关资源
最近更新 更多