通过指针vs end()访问std::vector元素
Accessing std::vector elements via pointers vs end()
我需要能够通过指针访问a和std::vector
的元素(只读,不涉及调整大小或类似的东西)。例如,
std::vector<int> foo(10);
int *ptr_begin = &foo[0];
到目前为止一切顺利,这保证在当前标准(23.3.6.1)中工作:
一个向量的元素是连续存储的,这意味着如果v是一个向量,而T不是bool类型,那么对于所有0 <= n
int *ptr_end = ptr_begin + foo.size()
(注意,我并没有试图访问过最后一个值,只是定义一个指向它的指针——如果你愿意,它相当于
foo.end()
)。标准中提到只能通过指针运算来访问元素,但显然这里我们并没有访问任何元素。(作为旁注,过去的东西存在的定义似乎与数组的基本概念紧密相关(例如参见5.7/5),但在整个标准中,似乎连续存储和数组的概念可以互换使用。我看错了吗?
是的,只要您只在比较*中使用ptr_end,并且不试图遵守它,这是可以的。引用c++ 11标准草案第5.7节关于指针加性操作的内容:
如果指针操作数和结果都指向相同的数组对象或数组对象最后一个元素的后面一个,评估不应产生溢出;否则,行为是未定义的。
在§5.9中为关系操作符列出了类似的规定:
如果两个指针指向同一数组的元素,或者指向数组以外的元素数组的末尾,指向下标较高的对象的指针比较高。
关于vector
的缓冲区是否算作一个数组,§8.3.4声明:
数组类型的对象包含连续分配的非空对象t型N个子对象的集合
这与§23.3.6.1关于vector
所说的是一致的:
vector的元素连续存储
由于指针是iterator
s,对于使用标准库算法将任意内存块作为输入来说,这是一个方便的技巧。例如,假设您想使用lower_bound
算法,但您的数据存储在MFC数组中:
CArray<int> someInts;
// populate and check for empty
int* begin = someInts.GetData();
int* end = begin + someInts.GetSize(); // for bounds-checking only; don't dereference
int* answer = std::lower_bound(begin, end, 100);
*还有一些其他的操作也是合法的;例如,既然你知道你的向量不是空的,你可以减去1来获得指向最后一个元素的指针。重要的是不要取消引用
您应该记住std::vector::data()
的存在,它显式地为您提供了指向该连续内存的指针。所以,是的,只读操作是可用的(如果你没有将它们与其他向量方法混合,这可能会在下面进行一些重新分配等)。
我甚至会更进一步-在std::vector::data()
下更改内存内容也应该是合法的。
是的,它是合法的,形成的地址到one-past-the-end元素。违抗它是不合法的。标准草案甚至有一个脚注,指出"实现只需要在对象结束后提供一个额外的字节(可能与程序中的另一个对象重叠),以满足"最后一个元素"的要求"。你也可以用它来做指针数学运算(至少是所有你在处理指向数组的指针时可以做的合法的事情)。
- 我想访问std::unique_ptr中的一个特定元素
- 为什么 std::itrator 无法访问该函数
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 如何访问存储在 std::variant 中的类的方法
- 通过unique_ptr访问std::数组
- 使用 std::vector<double> 访问由 std::unique_ptr<double[2] 管理的数据>
- 当键值是 std 向量时,为什么使用 at in C++ 访问映射值如此缓慢?
- 从 std::function in C++ 访问模板化 lambda
- 访问列表中的所有 std::变体,并为每次访问捕获附加值
- 访问 std:vector 的类成员 std:vector 在一个类中与另一个 std:vector
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问
- 使用 at() 访问 std::map 元素是否比运算符 [] 慢?
- 通过作为指向 C++ 函数的指针传递来访问 std::array 元素的正确方法是什么?
- 一个类似 std::访问的函数,用于访问多态类型
- 为什么必须STD ::访问具有单一返回类型
- 使用std :: bind with std ::访问
- STD ::访问与STD ::变体的工作
- 我可以将持有的类型从std ::变体中更改为从呼叫到std ::访问
- STD ::访问std ::变体无法正常工作
- 在std ::访问中获得主动价值,而又不知道哪个值是活动的