获取指向容器末尾的原始指针

Getting a Raw Pointer to the end of a Container

如果我有一个容器的 end iterator,但我想获得一个指向它的原始指针,有没有办法实现这个?

假设我有一个容器:foo。例如,我不能这样做:&*foo.end() 因为它会产生运行时错误:

Vector iterator not dereferencable

我可以做到这一点,但我希望有一种更简洁的方式到达那里:&*foo.begin() + foo.size()

编辑:

这不是一般如何将迭代器转换为指针的问题(显然这是问题所在),而是如何具体地将结束迭代器转换为指针。 "duplicate" question 中的答案实际上建议取消引用迭代器。结束迭代器 不能 在没有段错误的情况下被取消引用。

一般?编号

而你问的事实表明你的整体设计有问题。


向量、数组、字符串?当然……但是为什么呢?

只需获取指向有效元素的指针,然后推进它:

std::vector<T> foo;
const T* ptr = foo.data() + foo.size();

只要你不取消引用这样的指针(这几乎等同于取消引用迭代器,正如你在尝试中所做的那样),获取并持有这样的指针是有效的,因为它指向特殊的最后位置。

请注意,如果向量为空,&foo[0] + foo.size() 具有未定义的行为,因为 &foo[0]&*(foo.data() + 0)&*foo.data(),并且(就像在你的尝试) *foo.data() 如果那里什么都没有,则不允许。所以我们避免了所有的取消引用并简单地推进 foo.data() 本身。

无论如何,这仅适用于向量1、数组和字符串的情况。其他容器不保证(或可以合理预期提供)存储连续性;它们的结束指针几乎可以是任何东西,例如一个 "sentinel" 空指针,它不太可能对你有任何用处。

这就是迭代器抽象首先存在的原因。如果可以,请坚持使用它,而不是钻研原始指针的用法。


1. 除了 std::vector<bool>.

访问存储结束的正确方法是:

v.data() + v.size()

这是因为当v为空时*v.begin()无效

为所有连续容器(vectorstringarray)提供了成员函数data

从 C++17 开始,您还可以使用非成员函数:

data(v) + size(v)

这也适用于原始数组。