web-dev-qa-db-ja.com

nullに対してC ++イテレータをチェックできますか?

ベクトル反復子に問題があります。 nullイテレータをチェックすることは不可能であり、イテレータをチェックする通常の方法は、検索後にvector.end()に対してチェックすることであるといくつかの場所で読みました。たとえば、次のとおりです。

vector< Animal* > animalList;

vector<Animal*>::iterator findInList(const type_info& type)
{
    // Loop through list of Animals, if Dog found, return iterator to it
}

auto it = findInList(typeid(Dog));
// With a pointer I can check if it's null, but with an iterator I have to check against animalList.end();

問題は、コンテナが空になる可能性があることです。イテレータでは、コンテナが空であるか検索が失敗したことを示すためにnullを返すことができません。 vector :: end()を返すことはできますが、cplusplus.comのコメント:

If the container is empty, vector::end() function returns the same as vector::begin()

そしてvector :: begin()については次のように書かれています:

If the container is empty, the returned iterator value shall not be dereferenced.

したがって、空のコンテナがある場合、vector :: end()およびvector :: begin()は同じ場所を指し、参照解除できるとは思わず、割り当てられたメモリを指しているかどうかさえわかりません。

編集:みんなに感謝します。繰り返したように、vector :: end()またはvector :: begin()はイテレータを逆参照しません。vector:: end()に対して安全にチェックできます。

12
Zebrafish

イテレータがnullになることはないため、イテレータがnullかどうかを確認する必要はありません。返されたイテレータがコンテナのend()位置と異なるかどうかを確認する必要があります。そうであれば、_*it_によってイテレータを安全に逆参照できます。

コンテナが空の場合、返されるイテレータ値は逆参照されません。したがって、空のコンテナがある場合、vector :: end()およびvector :: begin()は同じ場所を指し、参照解除できるとは思わず、割り当てられたメモリを指しているかどうかさえわかりません。

いいえ、if(myIt != container.end())をチェックすると、イテレーターを逆参照しません。イテレータの逆参照は_*myIt_です。これは、イテレータが指しているオブジェクトの値を取得することを意味します。同じコンテナから他のイテレータへのイテレータをチェックすることは常に安全です。コンテナ要素を指していないイテレータを逆参照することは安全ではありません。

17
paweldac

いいえ、NULLではないため、NULLをチェックすることはできません。戻り、animalList.end()に対してもチェックします。反復子がend()と等しくない場合にのみ、それを逆参照する必要があります。

3
Mikel F

こんな感じで

auto it = findInList( someInfo );

if ( it == animalList.end() ) std::cout << "not found";
2