为什么使用std::next而不是向指针添加整数
Why use std::next instead of adding an integer to the pointer?
我有一个快速问题。我无法计算出使用std::next
相对于只向指针添加所需数量的进步的好处。一个简单的例子:
int main()
{
int arr [] = {1, 2, 3, 4, 5};
cout << *(arr + 2) << ", "; //example 1
cout << *std::next(arr, 2) << endl; //example 2
return 0;
}
输出:3, 3
从逻辑上讲,示例1应该更快,因为没有调用任何函数等。此外,在我运行此代码的实例中,如果我添加了一个会导致指针越界的数字(例如7),编译器会在示例1中抛出错误,但很乐意在示例2中继续给我一个内存地址。这与我最初的想法相矛盾:如果指针越界,std::next
会发出某种警告或其他什么。
任何启示都将不胜感激。
因为std::next
不仅设计用于原始指针,而且设计用于所有迭代器,因此它更通用。
你的假设也是错误的。当使用合理的优化级别时,这两种方法很可能会产生相同的装配。同样,c++的设计目的是使这种优化更容易。在您的示例中,底层迭代器类型显然是一个原始指针,并且推断函数调用可以内联是非常简单的。
编辑:
正如Matt在评论中所说,迭代器不仅仅有一个花哨的名称和模板包装器。有些数据结构(容器)不位于连续的内存段(例如map
或set
)中,它们需要使用更多的逻辑来计算内存中的确切位置。迭代程序也封装了这一点,它们提供了算法和容器之间的抽象级别。
因此,总结以上几点,使用标准习语有助于编写更健壮的代码,即支持不同类型的容器(不关心它们的内存布局),同时由于编译器非常智能,尽可能保持效率。
std::next
适用于所有迭代器类型。如果你知道你在处理一个数组,那么添加值就可以了。然而,如果您正在编写一个通用函数,希望在不同类型的迭代器上工作,这就带来了问题。
iter + 5
该操作仅为随机访问迭代器定义。
std::next(iter, 5)
然而,该操作是为前向迭代器定义的,这是一个更广泛的迭代器类别。简而言之,std::next
使您的代码更加通用。
cplusplus.com提供了各种迭代器类型支持的运算符的完整列表,可在此处获得。如该页面上的图表所示,所有随机访问迭代器也是正向的,但并非所有正向迭代器都是随机访问的。像链表这样的东西只适用于std::next
- 整数键映射到头文件中的成员函数指针
- 如何实现容纳整数和无效指针的双向链表?
- 使用指针将 ASCII 值添加到整数
- 如果整数与指针大小相同,则重新解释将整数转换为指针双射是否具有双射作用?
- 在C++中,如果我可以直接将整数分配给指针而不使用"new",为什么要使用"new"?
- 取消引用指向整数的指针时获得不同的结果
- 为什么此指针值不能转换为整数的规则是什么?
- 禁止指针和整数之间的比较C++
- 为什么在将 void 指针转换为整数指针时出现分段错误
- ISO C++禁止指针和整数 [-fpermissive] [c++] 之间的比较
- 指向整数数组和打印总和的指针
- 将uint64_t转换为字节时从不同大小的整数强制转换为指针
- Qt 错误 iso c++ 禁止指针和整数之间的比较 -permissive
- 如何在 c++ 中动态声明指向整数的指针数组?
- C++:这是使用整数变量作为函数调用指针的正确方法吗
- 如何在满足常量表达式的同时将整数传递给指针,传递给 std::array<double、integer>?
- 创建<int>对整数数组指针的矢量引用 (C++)
- 整数指针数组的元素是否可以指向整数数组?
- 将指针整数(int**)转换为c中的String
- 为什么此指针/整数比较会生成分段错误