2017-01-13 5 views
1

私はstd::array<SomeType, N>があると仮定し、イテレータを使用する関数をstd::arrayのオブジェクトで動作させたいと考えていますが、コンテナについては知らずにstd::arrayです。イテレータを使ってオブジェクト操作を実行する関数

int main() { 
    std::array<SomeType, 10> a; 

    action<std::array<SomeType, 10>::iterator>(a.begin(), a.end()); 
} 

しかし:この関数を呼び出すとすることにより可能である

template<typename Iterator> 
void action(Iterator &beg, Iterator &end) { 
    for (; beg != end; ++beg) 
    beg->doSomething(); 
} 

SomeTypeは、パブリックメンバ関数のdoSomething()

は、例えば関数があるかもしれないを持つクラスでありますこれをやり遂げる方法があるのだろうか?特に、各クラスにテンプレートを使用できるためです。コンテナがstd::arrayであることを関数に知らせずに、関数をSomeTypeに制限する方法はありますか?

+0

書かれたコードはコンパイルされません。少なくとも、それは正しい形式のC++ではありません。 [デモ](http://melpon.org/wandbox/permlink/tw8f7mpNxZTZel9X) –

答えて

5
  1. lvalue引数は必要ありません。実際、イテレータは効率的にコピー可能であることを意図しています。標準ライブラリは、すでにいくつかの上で同じことをやって」の一般的なケースをカバーする多数のアルゴリズムを持っていることを

    action(a.begin(), a.end()); 
    
+0

[デモ](http://melpon.org/wandbox/permlink/IftDha8EQMpKdWhi) –

0

注:

template<typename Iterator> 
void action(Iterator beg, Iterator end) 
//   ^^^^^^^^^^^^ ^^^^^^^^^^^^ 
  • レッツテンプレート引数控除は、その仕事をしますいくつかの容器の範囲 ":

    #include <array> 
    #include <vector> 
    #include <algorithm> 
    #include <numeric> 
    #include <iterator> 
    
    struct SomeType 
    { 
        void doSomething(); 
    
        SomeType mutatedCopy() const; 
    
        int someValue() const; 
    }; 
    
    int add_value(int i, const SomeType& st) { 
        return i + st.someValue(); 
    } 
    
    void call_something(SomeType& st) { st.doSomething(); } 
    auto mutate_copy(SomeType const& st) { return st.mutatedCopy(); } 
    
    int main() { 
        std::array<SomeType, 10> a; 
        std::vector<SomeType> b; 
    
        std::for_each(a.begin(), a.end(), call_something); 
        std::for_each(b.begin(), b.end(), call_something); 
    
        std::transform(a.begin(), a.end(), a.begin(), mutate_copy); 
        std::transform(b.begin(), b.end(), b.begin(), mutate_copy); 
    
        auto tot = std::accumulate(a.begin(), a.end(), 0, add_value) 
          + std::accumulate(b.begin(), b.end(), 0, add_value); 
    
        // you can even transform into dissimilar containers: 
    
        std::transform(a.begin(), a.end(), std::back_inserter(b), mutate_copy); 
    
    } 
    
  • 関連する問題