2016-04-29 8 views
2

最近、私は今インデックスによるベクトルイテレータへのアクセス?

auto toDelete = std::make_shared<std::string>("FooBar"); 
std::vector<decltype(toDelete)> myVec{toDelete}; 
auto iter = std::find_if(std::begin(myVec), std::end(myVec), 
    [](const decltype(toDelete) _next) 
    { 
     return *_next == "FooBar"; 
    }); 

if (iter != std::end(myVec)) 
{ 
    std::shared_ptr<std::string> deletedString = iter[0]; 
    std::cout << *deletedString; 
    myVec.erase(iter); 
} 

Online Example

(もちろん、ここのために簡素化された)私のコードベースでは、このコードに出くわした、私はここで、我々はインデックスでイテレータにアクセスしていることに気づきました!ので、すべての私が推測することができ、私は誰もが前にインデックスでイテレータにアクセス見たことがない

std::shared_ptr<std::string> deletedString = iter[0]; 

は、イテレータはポインタのように扱われます、そして、我々は最初の要素は、ポインタで指さのアクセスという点です。そのコードは実際には次のコードと同等です:

std::shared_ptr<std::string> deletedString = *iter; 

またはそれは未定義の動作ですか? RandomAccessIteratorためcppreference documentationから

+2

'x [y]'は(この場合) '*(x + y)'とまったく同じです。イテレータにゼロを追加しても、イテレータは変更されません。だから 'iter [0]'は '* iter'と同じです。 –

答えて

5

式:i[n]

操作的意味論:*(i+n)

std::vectorのイテレータはRandomAccessIteratorの要件を満たしているので、それらのインデックスを作成することに相当します通常のポインタのように、追加と逆参照があります。 iter[0]*(iter+0)または*iterに相当します。

4

これは、適合動作Standardある

1クラスまたはポインタ型Xは、ランダムアクセスイテレータ の要件を満足する[random.access.iterators]

24.2.7ランダム・アクセス・イテレータ双方向の イテレータの要件を満たすことに加えて、次の式が表118に示すように有効である場合には、表118に示すように有効です。

012参考まで転換:それがあること*(a + n)

特定のイテレータはポインタとして実装される必要はない。オーバーレイされたoperator[]operator*、およびoperator+の上記のセマンティクスを持つイテレータクラスは動作します。 std::vectorの場合、イテレータカテゴリはランダムアクセスイテレータであり、が必要です。が動作する必要があります。