2011-07-08 8 views
0

通常のアルゴリズムテンプレートは、これらのイテレータの代わりに2つのイテレータを受け入れるように設計されているのはなぜですか?私は(COPY2の冗長性を削減:2つのイテレータを受け入れるテンプレート

#include <iostream> 
#include <iterator> 
#include <vector> 

using namespace std; 

template <typename Range, typename OutputIterator> 
void copy2 (Range r, OutputIterator o) { 
    copy (r.first, r.second, o); 
} 

template <typename iter1, typename iter2> 
pair<typename iter1, typename iter2> Range(iter1 start, iter2 end) { 
    return make_pair(start, end); 
} 

int main() 
{ 
    vector<int> myvector; 
    myvector.push_back(3); 
    myvector.push_back(2); 
    myvector.push_back(1); 

    // ordinary algorithm template accepts two iterators 
    copy(myvector.begin(), 
     myvector.end(), 
     ostream_iterator<int> (cout,"\n")); 

    // this template accepts iterator Range 
    copy2(Range(myvector.begin(),myvector.end()), 
      ostream_iterator<int> (cout,"\n")); 
} 

(コピーの理由からどのようなもの)COPY2よりも優れている()[COPY2以外()冗長を呼び出す]

EDIT:この例で考えてみましょう)DeadMGが提案したように大量に。

+0

イテレータをペアにラッピングする利点は何ですか?私が見ているのは、より多くのタイピングとペアタイプへの依存が必要だということだけです。 –

+0

copy2()の冗長性は十分な理由ではありませんか? –

+0

@ジョー:それは本当ですが、それは少しの想像力で簡単に解決できます。 – Puppy

答えて

1

本当に? 1つではありません。私が知る限り、標準化される前に誰も範囲を思い出さなかったので、標準ライブラリにはイテレータの概念しかありません。多くの人々は、範囲を使用することで大幅に改善できると考えています。第2に、少し余分な事前に書かれたボイラーで#2の冗長性を簡単に改善することができます。

template<typename T> std::pair<typename T::const_iterator, typename T::const_iterator> all(const T& t) { 
    return std::make_pair(t.begin(), t.end()); 
} 
template<typename T> std::pair<typename T::iterator, typename T::iterator> all(T& t) { 
    return std::make_pair(t.begin(), t.end()); 
} 

copy2(all(myvector), ostream_iterator<int>(cout, "\n")); 
+0

すばらしい答えをありがとう! –

0

私は物事を単純なものとして維持しています。あなたのイテレータを別のコンテナにラップすると、あなたのcopy2関数のためのより小さい署名以外にあなたは何を与えますか? (個人的にはペアでラッピングする利点はありませんので、関数を呼び出すためのコードを書いてください)

投稿したサンプルコードを見ると、元のコピーコールは(IMO )copy2コールよりもはるかに読みやすい。

+0

ですが少し想像力でもっときれいにすることができます。 – Puppy

+0

本当ですか、なぜですか?より多くのコード(不要なtypedefを追加することさえも)は、より多くのエラーを引き起こします。関数(container.begin()、container.end())はすでにクリアされています。一般的なプログラミングでは、 "range"オブジェクトにラッピングすることはありません。あなたがフォワードイテレータの上にリバースイテレータを持つことを開始すると思います。より多くのtypedefを作成してください。 (確かに、範囲がうまくいくかもしれない特定のケースがあり、そのようなケースでは、OPコピーcopy2のようなラッパー関数をコード化する能力がありますが、これは例外であり標準ではないと言います) – MarkD

+0

対処すべてのコンテナが標準です。範囲を扱うことは、イテレータを扱うよりもはるかに一般的です。範囲を扱うことが最適化された場合、誰にとっても大きなメリットがあります。 – Puppy

0

私はそれはあなたがすでに一つのイテレータを持っている場合は、アルゴリズムを呼び出すためにペアを構築する必要がないことだし、それはアルゴリズムに一貫性のあるすべての引数を保持しているとします。いくつかの並べ替えのイテレータを(おそらく述語)。

+0

しかし、すでにペアがあり、そのペアのみを参照できる場合はどうなりますか? –

0

copy2には、2つのイテレータからペアを構築する必要があり、少しオーバーヘッドがあります。それほど大したことではないかもしれませんが、必要でない場合に余分な計算を加える理由はありません。

また、コードをできるだけ理解しやすくすることのメリットは過小評価されるべきではありません。

+2

まともなコンパイラではありません。 – Puppy

関連する問題