Kon*_*app 10 c++ pointers c++11
我只是有一个简短的问题.我无法弄清楚使用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;
}
Run Code Online (Sandbox Code Playgroud)
输出: 3, 3
从逻辑上讲,示例1应该更快,因为没有调用函数等.此外,在我运行此代码的实例中,如果我添加了一个会导致指针超出范围的数字(例如7),编译器会在示例1中抛出一个错误,但很高兴继续在示例2中给我一个内存地址.这与我最初的想法相矛盾:std::next如果指针超出界限,会发出某种警告或某些事情.
任何启蒙都会受到赞赏.
luk*_*k32 12
因为std::next它不仅适用于原始指针,而且适用于所有迭代器,因此它更通用.
你的假设也是假的.当使用合理的优化级别时,这两种方法很可能会导致相同的程序集.同样,c ++旨在使这种优化更容易.在您的示例中,底层迭代器类型显然是一个原始指针,并且推断函数调用可以内联是非常简单的.
编辑:
正如Matt在他的评论中所说,迭代器不仅仅是一个奇特的名字和一个模板包装器.有些数据结构(容器)不存在于连续的内存段(例如a map或set)中,它们需要使用更多逻辑,以确定内存中的确切位置.迭代器也包含它,它们在算法和容器之间提供了一定程度的抽象.
因此,总结以上几点,使用标准习语有助于编写更强大的代码,即支持不同类型的容器(不关心其内存布局),同时由于相当聪明的编译器而在可能的情况下保持效率.
Sil*_*olo 11
std::next适用于所有迭代器类型.如果您知道自己正在处理数组,那么添加该值就可以了.但是,如果您正在编写要在不同类型的迭代器上工作的泛型函数,则会产生问题.
iter + 5
Run Code Online (Sandbox Code Playgroud)
该操作仅为随机访问迭代器定义.
std::next(iter, 5)
Run Code Online (Sandbox Code Playgroud)
但是,该操作是为前向迭代器定义的,前向迭代器是一个更广泛的迭代器类别.简而言之,std::next使您的代码更加通用化.
cplusplus.com有各种迭代器类型支持的运算符的完整列表,可在此处获得.如该页面上的图表所示,所有随机访问迭代器也都是前向的,但几乎并非所有前向迭代器都是随机访问.链接列表之类的东西只适用于std::next