2016-07-08 9 views
0

:最後の行でstd :: uniqueはベクトルイテレータを無効にしますか?このコードの場合

std::vector<int> v = {...}; 
std::sort(v.begin(), v.end()); 

// Does this work? 
std::size_t unique_count = std::unique(v.begin(), v.end()) - v.cbegin(); 

は、私はstd::uniqueがちょうどベクトル内の周りに詰め込むを移動し、そこには何も挿入していないので、何のイテレータを無効にすべきではないと思うし、そう私は道unique_countを計算することが正しいはずです。しかし、私はそれが事実であることを確認したい。それは...ですか?

+1

いいえ、それはしません。 2つのイテレータを渡すだけなので、コンテナにアクセスすることさえできません。 – songyuanyao

+0

@songyuanyaoだから、 'unique_count'は正しいです。右? –

+0

はい、大丈夫でしょう。 – songyuanyao

答えて

3

std::uniqueアルゴリズムです。すべてのstlアルゴリズムは、コンテナではなく範囲で動作します。

アルゴリズムは要素の内容を入れ替えることができますが、それらの要素に対する反復子は変更されません。

これは保証です。

それがなかったら、これは動作しませんでしたが:

#include <algorithm> 
#include <vector> 
#include <iostream> 
#include <array> 

int main() 
{ 

    auto unique_size = [](auto&& container) 
    { 
    std::sort(std::begin(container), std::end(container)); 
    return std::unique(std::begin(container), std::end(container)) - std::cbegin(container); 
    }; 

    std::cout << unique_size(std::vector<int> {6,5,4,4,3,2,1}) << std::endl; 
    std::cout << unique_size(std::array<int,7> {6,5,4,4,3,2,1}) << std::endl; 
    int x[] = {6,5,4,4,3,2,1}; 
    std::cout << unique_size(x) << std::endl; 

    // Does this work? yes. 
} 

義務付け出力:

6 
6 
6 
2

std::uniqueコンテナ内の最後の「ユニーク」要素を過ぎた1つの位置にイテレータを返します。

auto last = std::unique(v.begin(), v.end()); 

そして、範囲[lastv.end()は)あなたがv.cbegin()に頼ることができないものは何でも、含まれています。代わりに:

auto unique_count = std::distance(v.begin(), last); 

トリックを行います。

http://en.cppreference.com/w/cpp/algorithm/unique

+1

'v.cbegin()'に頼ることができないのはどういう意味ですか? –

+0

申し訳ありませんが、私はコンテンツが[last、end()]から失われたことを意味しました。私は手動で違いを作る代わりにstd :: distanceを使います。 –

+0

基本的に 'std :: distance'は' last-v.begin() 'と同じことをここで行います。 – songyuanyao

関連する問題