【问题标题】:Cast of const_iterator to iterator& in definition of std::set在 std::set 的定义中将 const_iterator 转换为 iterator&
【发布时间】:2017-05-03 01:52:50
【问题描述】:

C++ STL 使用红黑树在std::setstd::map 中存储数据。我注意到set::iterator实际上是红黑树的const迭代器的typedef:

//All code snippets taken from SGI STL. https://www.sgi.com/tech/stl/

typedef _Rb_tree<key_type, value_type, _Identity<value_type>, key_compare, _Alloc> _Rep_type;
typedef typename _Rep_type::const_iterator iterator;

这是合理的,因为用户不应该通过迭代器修改集合的内容。但是set 必须实现像inserterase 这样的操作,这需要红黑树的非常量迭代器。 SGI STL 使用 c 风格的转换来做到这一点:

void erase(iterator __position) { 
  typedef typename _Rep_type::iterator _Rep_iterator;
  _M_t.erase((_Rep_iterator&)__position); 
}

我想知道:

  1. 为什么这个演员表是安全的?它将_Rep_type::const_iterator 转换为_Rep_type::iterator&amp;
  2. 如何以 C++ 风格编写演员表? I've tried to do itstatic_castconst_cast 都不会完成这项工作。 reinterpret_cast 可以编译,但我不确定它是否与 C 风格的转换相同。

【问题讨论】:

  • Re:“const 迭代器的 typedef”——这里要非常小心:它实际上是“const_iterator 的 typedef”。 “const_iterator”不是“const iterator”,反之亦然。 “const_iterator”不能用于修改它指向的数据。 “const 迭代器”本身不能被修改,但它可能会也可能不会修改它指向的数据,这取决于它是否实际上是一个 const_iterator。

标签: c++ casting stl iterator set


【解决方案1】:

iterator_Rep_type::iterator 是同一个类模板的实例,前者使用const 限定类型,后者使用相同但非const 类型。像这样的:

template <class T, class U>
struct B {};

using S = B<int&, int*>;
using Sconst = B<const int&, const int*>;

所以对于你的问题:

  1. 这是安全的,因为这两种类型的内存布局完全相同。
  2. 您不能使用static_cast,因为编译器认为这些类型是不相关的。你得带上重炮,reinterpret_cast
int test() {
    S s;
    Sconst& sconst = reinterpret_cast<Sconst&>(s);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 2016-08-16
    • 2019-11-04
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多