更喜欢过度指针的迭代器? [英] Prefer Iterators Over Pointers?

查看:193
本文介绍了更喜欢过度指针的迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是一个有评论的问题 here 但作为凹凸的一部分被删除。

This question is a bump of a question that had a comment here but was deleted as part of the bump.

对于那些看不到删除帖子的人,评论是我使用 const char * 而不是 string :: const_iterator 此答案中的code>:迭代器可能是一个更好的路径,因为它出现了这正是你的指针的处理方式。

For those of you who can't see deleted posts, the comment was on my use of const char*s instead of string::const_iterators in this answer: "Iterators may have been a better path from the get go, since it appears that is exactly how your pointers seems be treated."

所以我的问题是这样,迭代器持有 string :: const_iterator s在 const char * 上保留任何内在值,以便将我的答案转换为 string :: const_iterators 有意义吗?

So my question is this, do iterators hold string::const_iterators hold any intrinsic value over a const char*s such that switching my answer over to string::const_iterators makes sense?

推荐答案

简介



有ma使用迭代器而不是指针的好处是:

Introduction

There are many perks of using iterators instead of pointers, among them are:


  • 发布中的不同代码路径 vs debug ,和;

  • 更好的类型安全性,并且;

  • 可以编写通用代码(迭代器可以是使用任何数据结构,如链接列表,而内在指针在这方面非常有限)。

  • different code-path in release vs debug, and;
  • better type-safety, and;
  • making it possible to write generic code (iterators can be made to work with any data-structure, such as a linked-list, whereas intrinsic pointers are very limited in this regard).

除其他外,取消引用传递的迭代器范围的结尾是 undefined-behavior ,在这种情况下,实现可以自由地做任何必要的事情 - 包括提出诊断,说你做错了。

Since, among other things, dereferencing an iterator that is passed the end of a range is undefined-behavior, an implementation is free to do whatever it feels necessary in such case - including raising diagnostics saying that you are doing something wrong.

提供标准库实现, libstdc ++ ,通过 gcc 会在检测到故障时发出诊断信息(如果 调试模式 已启用。)

The standard library implementation, libstdc++, provided by gcc will issues diagnostics when it detects something fault (if Debug Mode is enabled).

示例

#define _GLIBCXX_DEBUG 1 /* enable debug mode */

#include <vector>
#include <iostream>

int
main (int argc, char *argv[])
{
  std::vector<int> v1 {1,2,3};

  for (auto it = v1.begin (); ; ++it)
    std::cout << *it;
}



/usr/include/c++/4.9.2/debug/safe_iterator.h:261:error: attempt to 
    dereference a past-the-end iterator.

Objects involved in the operation:
iterator "this" @ 0x0x7fff828696e0 {
type = N11__gnu_debug14_Safe_iteratorIN9__gnu_cxx17__normal_iteratorIPiNSt9__cxx19986vectorIiSaIiEEEEENSt7__debug6vectorIiS6_EEEE (mutable iterator);
  state = past-the-end;
  references sequence with type `NSt7__debug6vectorIiSaIiEEE' @ 0x0x7fff82869710
}
123

如果我们使用指针,无论我们是否处于调试模式,都不会发生上述情况。

The above would not happen if we were working with pointers, no matter if we are in debug-mode or not.

如果我们不要为 libstdc ++ 启用调试模式,将使用性能更友好的版本(没有添加的簿记)实现 - 并且不会发布任何诊断信息。

If we don't enable debug mode for libstdc++, a more performance friendly version (without the added bookkeeping) implementation will be used - and no diagnostics will be issued.

由于迭代器的实际类型是实现定义的,这可用于提高类型安全性 - 但您必须检查实现的文档看看是否是这种情况。

Since the actual type of iterators are implementation-defined, this could be used to increase type-safety - but you will have to check the documentation of your implementation to see whether this is the case.

考虑下面的例子:

#include <vector>

struct A     { };
struct B : A { };

                                                      // .-- oops
                                                      // v
void  it_func (std::vector<B>::iterator beg, std::vector<A>::iterator end);

void ptr_func (B * beg, A * end);
                     // ^-- oops

int
main (int argc, char *argv[])
{
  std::vector<B> v1;

   it_func (v1.begin (), v1.end  ());               // (A)
  ptr_func (v1.data  (), v1.data () + v1.size ());  // (B)
}

精化


  • (A)取决于实现,可以是编译时间错误,因为 std :: vector< A> :: iterator std :: vector< B> :: iterator 可能不是同一类型。

  • (B)总是编译,因为从 B隐式转换* A *

  • (A) could, depending on the implementation, be a compile-time error since std::vector<A>::iterator and std::vector<B>::iterator potentially isn't of the same type.
  • (B) would, however, always compile since there's an implicit conversion from B* to A*.

这篇关于更喜欢过度指针的迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆