2011-02-07 8 views
0

私はテンプレートを初めて使用しています。何かを行うためにテンプレートを使用する必要がありますが、テンプレート機能を呼び出す方法はわかりません。それはおそらく単純な単純ですが、私はそれを見ることはできません。テンプレートの署名の問題

template<class It, class T> 


// iterator and value_type of *It 
void Calc(It begin, It end, std::pair<int, int> &out) 
{ 
     std::vector<It>::iterator iter; 
    std::map<int, int> StartMap; 
    std::map<int, int>::reverse_iterator rit; 

    int sum, start, stop, count; 
    start = stop = 1; 
    count = sum = 0; 

    for(iter = begin; iter != end; iter++) 
    { 
     sum += iter; 
     count++; 
     stop++; 
     if(sum <= 0) 
     { 
      // store original start 
      StartMap.insert(start, count); 
      // set new start position 
      start = stop; 
     } 
    } 

    // set iterator to highest value 
    rit = StartMap.rbegin(); 

    start = rit->first; 
    stop = start + rit->second; 

    out.insert(start, stop); 
} 

しかし、私が2 std :: vector iteratorsをどのように呼び出すかはわかりません。 私はあなたがそれoutを与えたいので、この

void doSomething(std::vector<int>& stopsVec) 
{ 
    std::pair<int, int> out; 
    Calc<std::vector<int>::iterator, std::pair<int, int>>(stopsVec.begin(), stopsVec.end(), &out); 
} 
+2

あなたはテンプレートパラメータ 'T'をまったく使用していないようです。 – Tim

+0

あなたの問題がその関数を呼び出すと思われるエラーは何ですか? – JaredC

答えて

4
void doSomething(std::vector<int>& stopsVec) 
{ 
    std::pair<int, int> out; 
    Calc<std::vector<int>::iterator, std::pair<int, int> > 
     (stopsVec.begin(), stopsVec.end(), out); // not &out 
} 

Calcは、std::pair<int, int>への参照を取るしようとしました。 &outを渡すと、ペアにポインタを渡そうとします。これは動作しません。署名を想定し

EDIT

は実際には次のとおりです。

template<class It> 
void Calc(It begin, It end, std::pair<int, int> &out) 

あなたがでそれを呼び出すことができます。コンパイラはせずに、パラメータから正しいテンプレートの種類を推定することができます

Calc(stopsVec.begin(), stopsVec.end(), out); 

間に指定する必要があります<>

EDIT

キースは、以下の点で優れています。それはあなたがここで持っている別のコンパイルエラーです。また、次の点にご注意ください:

sum += iter; 

あなたが望むものはありません。あなたはおそらく意味:

sum += *iter; 

しかしsumので、int型で、かつiterは、テンプレートの種類で、これは本当に汎用テンプレートメソッドではありません。実際には、数値型のイテレータでしか動作しません。

そして、一つの他の問題:

Calc<std::vector<int>::iterator, std::pair<int, int> > // use a space 
    (stopsVec.begin(), stopsVec.end(), out); 

代わりの

Calc<std::vector<int>::iterator, std::pair<int, int>> // ">>" is shift operator 
    (stopsVec.begin(), stopsVec.end(), out); 

あなたはテンプレートの構文を持つために閉じ>兆候との間のスペースを必要としています。それ以外の場合は、ビットシフト(またはストリーム抽出)を行っています。コンパイラは、その時点から何も意味をなさないため、混乱します。

0

注こと:

template<class It, class T> 
void Calc(It begin, It end, std::pair<int, int> &out) 
{ 
    std::vector<It>::iterator iter; 
    for(iter = begin; iter != end; iter++) 

は間違っています。

template<class It, class T> 
    void Calc(It begin, It end, std::pair<int, int> &out) 
    { 
     It iter; 
     // etc. 
     for(iter = begin; iter != end; iter++) 

しかし、また、C++で、一般的アプローチ「初期設定で宣言」に従うことが好ましいことに注意してくださいので、これは次のようになります:それはおそらくあるべき

template<class It, class T> 
     void Calc(It begin, It end, std::pair<int, int> &out) 
     { 
      // etc. 
      for(It iter = begin; iter != end; iter++) 
0

あなたがする必要はありません反復される型をテンプレート引数として明示的に渡します。 STLの設計者は非常に賢明だったと、これは頻繁に来ることに気づき、そして次のように、それは根本的なタイプです取得するイテレータの種類にイントロスペクションする(非常にきれいしかし、完全に正確ではない)方法があります:

一度
typedef typename std::iterator_traits<It>::value_type value_type; 

これを行った後、value_typeという名前を使用して、反復処理される型を参照できます。これは、今、必要な補助型が存在しないことを、あなたは直接

std::vector<int> v = /* ... */ 
std::pair<int, int> result; 
Calc(v.begin(), v.end(), result); 

としての機能を呼び出すことができますうまくいけば、これは簡単です、あなたは

template <typename It> 
void Calc(It begin, It end, std::pair<int, int>& out) { 
    typedef typename std::iterator_traits<It>::value_type value_type; 
    /* ... Rest of the code, now using this type ... */ 
} 

としてテンプレート関数を書き換えるとの契約を密封することができます読み書きする!

関連する問題