如果容器元素是指针,为什么我允许从const_iterator调用非const成员函数?

Sam*_*rsa 4 c++ iterator const

请考虑以下代码:

#include <vector>
using namespace std;

struct foo
{
  void bar()
  {
  }
};

int main()
{
  {
    vector<foo*> a;
    a.push_back(new foo());
    a.push_back(new foo());
    a.push_back(new foo());

    vector<foo*>::const_iterator itr = a.begin();
    (*itr)->bar(); // compiles - this becomes more confusing 
                   // when found in a const method. On first 
                   // glance, one will (or at least me) may
                   // assume that bar() must be const if the 
                   // method where it is being called from is 
                   // const

    // The above compiles because internally, this is what happens 
    // (ignore the fact that the pointer has not been newd)
    foo* const * element;
    (*element)->bar(); // compiles

    // What I would expect however (maybe it is just me) is for const_iterator
    // to  behave something like this
    const foo* const_element;
    const_element->bar(); // compile error
  }

  {
    vector<foo> a;
    a.resize(10);

    vector<foo>::const_iterator itr = a.begin();
    itr->bar(); // compile error
  }

}
Run Code Online (Sandbox Code Playgroud)

我理解为什么可以这样称呼它.的const_iterator存储常量性是这样的:const T*其用于指针转换为foo* const *和为对象foo const *.

所以我的问题是,为什么我们允许从一个非const成员函数调用const_iterator?不允许从一个非const成员函数调用是否更直观const_iterator?不应该iterator用const选项设计s可以防止这种行为吗?

现在更重要的问题是:如果我想const_iterator禁止调用指向对象的非const成员函数,该怎么办?

Nic*_*las 5

不应该使用const选项设计迭代器来防止这种行为吗?

确实如此.你只是期望它是一个不同的操作.

正如您所发现的,指针容器......包含指针,而不是对象.因此,const_iterator这样的指针意味着指针是恒定的,而不是它们指向的对象.

这不会改变,也不会改变.标准库容器通常设计为包含完整的对象,而不是指针.所以他们不应该鼓励用户使用vector指针和其他可疑的结构.

如果你真的需要一个vector包含指针,那么你应该使用一个实际设计的容器.就像Boost的指针容器类一样.他们const_iterators使物体const正确指向.他们还做其他有用的事情,比如拥有他们指向的对象(以便正确删除它们)等等.