3

この質問は、ここにコメントがありましたが、バンプの一部として削除された質問のバンプです。

削除された投稿を見ることができない人のために、コメントはこの回答const char*で s の代わりにstring::const_iterators を使用したことに関するものでした。扱われます。」

だから私の質問はこれです、イテレータはstring::const_iterators を s よりも本質的な値を保持しているconst char*ので、私の答えをに切り替えることは理にstring::const_iteratorsかなっていますか?

4

2 に答える 2

6

序章

ポインターの代わりにイテレーターを使用することには多くのメリットがあります。

  • releasedebugで異なるコードパス、および;
  • より良い型安全性、および;
  • ジェネリック コードを記述できるようにする (反復子は、リンク リストなどの任意のデータ構造で動作するように作成できますが、組み込みポインターはこの点で非常に制限されています)。


デバッグ

とりわけ、範囲の終わりを渡されたイテレータの逆参照はundefined-behaviorであるため、実装は、そのような場合に必要と思われることを自由に行うことができます。

gccが提供する標準ライブラリの実装であるlibstdc++は、何らかの障害を検出すると診断を発行します (デバッグ モードが有効な場合)。


#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

デバッグモードであるかどうかに関係なく、ポインターを使用している場合、上記は発生しません。

libstdc++のデバッグ モードを有効にしない場合、よりパフォーマンスに適したバージョン (ブックキーピングを追加しない) の実装が使用され、診断は発行されません。



(潜在的に) より良い型安全性

イテレータの実際の型はimplementation-definedであるため、これを使用して型安全性を高めることができますが、実装のドキュメントをチェックして、これが当てはまるかどうかを確認する必要があります。


以下の例を考えてみましょう:

#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*ます。
于 2015-03-17T12:57:04.253 に答える