【发布时间】:2015-12-18 12:59:27
【问题描述】:
在 Herb Sutter 的 When Is a Container Not a Container? 中,他展示了一个将指针放入容器的示例:
// Example 1: Is this code valid? safe? good?
//
vector<char> v;
// ...
char* p = &v[0];
// ... do something with *p ...
然后进行“改进”:
// Example 1(b): An improvement
// (when it's possible)
//
vector<char> v;
// ...
vector<char>::iterator i = v.begin();
// ... do something with *i ...
但并没有真正提供令人信服的论据:
一般来说,更喜欢使用迭代器并不是一个糟糕的指导方针 当您想要指向位于 a 中的对象时,指针 容器。毕竟,迭代器在几乎相同的情况下失效 时间和与指针相同的方式,以及迭代器的原因之一 存在是提供一种“指向”包含对象的方法。所以,如果你 有一个选择,更喜欢在容器中使用迭代器。
不幸的是,迭代器无法始终获得相同的效果 您可以使用指向容器的指针。主要有两个 迭代器方法的潜在缺点,当任何一个适用时,我们 不得不继续使用指针:
在可以使用指针的地方,您不能总是方便地使用迭代器。 (见下面的例子。)
在迭代器是一个对象而不仅仅是一个秃头的情况下,使用迭代器可能会产生额外的空间和性能开销 指针。
在向量的情况下,迭代器只是一个 RandomAccessIterator。出于所有意图和目的,这是对指针的薄包装。一种实现甚至承认这一点:
// This iterator adapter is 'normal' in the sense that it does not
// change the semantics of any of the operators of its iterator
// parameter. Its primary purpose is to convert an iterator that is
// not a class, e.g. a pointer, into an iterator that is a class.
// The _Container parameter exists solely so that different containers
// using this template can instantiate different types, even if the
// _Iterator parameter is the same.
此外,该实现存储_Iterator 类型的成员值,即pointer 或T*。换句话说,只是一个指针。此外,这种类型的difference_type 是std::ptrdiff_t,定义的操作只是简单的包装(即operator++ 是++_pointer,operator* 是*_pointer)等等。
按照 Sutter 的论点,这个迭代器类对指针没有任何好处,只有缺点。我说的对吗?
【问题讨论】:
-
没有
restrict,谈论它们的性能是没有意义的。 -
似乎问题在于通过调用指针迭代器的组织薄包装器来欺骗自己。如果您将指针称为指针并将迭代器术语保留为仅指向容器的一系列成员中的一个的事物等,那么它将成为具有保护措施的迭代器和没有保护措施的指针之间的真正选择。
标签: c++ pointers vector iterator gotw