2016-07-12 13 views
0

私はどのソートされていない範囲のユニークな要素の数数えることができる機能unique_countがあるとします。私はしたくないので、私は新しいvectorを作成左辺値と右辺値の両方に割り当て参照

template<typename InputIt> 
std::size_t unique_count(InputIt first, InputIt last) 
{ 
    using T = typename std::iterator_traits<InputIt>::value_type; 

    std::vector</* ??? */> v(first, last); 
    std::sort(v.begin(), v.end()); 
    return std::distance(v.begin(), 
         std::unique(v.begin(), v.end())); 
} 

を元のコンテナを変更しますが、私は不要なコピーをしたくありません。最も簡単な解決策はポインタのベクトルを作ることですが、*firstconst T&(たとえば、vector)またはT(ストリームから)のいずれかを返すことがあります。

したがって、/* ??? */の部分は、const T&と概念的に同等である必要があります。 vectorは参照を保持することができないので、実際にはこれを行うことはできません。割り当てが解除されています。 reference_wrapper<const T>のいずれも使用できません。なぜなら、一時的なものからは構成できないからです。

どのような代替手段がありますか?

答えて

2

Tまたはconst T&のいずれかで構成されているかどうかによって、Tオブジェクトを所有する場合としない場合があります。明らかな理由から、そのようなタイプは一般に避けなければならない。

*firstが参照型または非参照型を返すかどうかによって、タグディスパッチまたはSFINAEを使用して、2つの実装のいずれかを選択することもできます。

もう1つの方法は、アルゴリズムを狭めて前方イテレータのみを受け入れる方法です。ここでは、単に店が自分自身をイテレータすることが可能と要素を比較するためにそれらを使用することが保証さを指摘されています

template <typename ForwardIt> 
std::size_t unique_count(ForwardIt first, ForwardIt last) { 
    std::vector<ForwardIt> v; 
    for (auto i = first; i != last; ++i) { 
     v.push_back(i); 
    } 
    const auto pred = [](ForwardIt a, ForwardIt b) { return *a < *b; }; 
    std::sort(v.begin(), v.end(), pred); 
    return std::distance(v.begin(), std::unique(v.begin(), v.end(), pred)); 
} 
+0

は今、私はT 'と '間のベクトル値の種類を選択するために'のstd :: conditional'を使用しています'reference_wrapper ' 'is_lvalue_reference :: value'に依存します。これは合理的なアプローチだと思いますか? –

+0

@ZizhengTai私にはうってつけの音です。 – Brian

関連する問題