2011-05-23 17 views
2

私はテンプレートとSTLを使って実験を行っています。これは...C++、std :: copyとtemplates

template <typename Item> 
struct TList 
{ 
    typedef std::vector <Item> Type; 
}; 

template <typename Item> 
class Cont 
{ 
private: 
    typename TList <Item>::Type elements; 

public: 
    void push_back (const Item & p) {elements.push_back (p);} 

    typename TList <Item>::Type ::iterator 
     copy (typename TList <Item>::Type ::iterator first, 
       typename TList <Item>::Type ::iterator last, 
       typename TList <Item>::Type ::iterator result) 
     { 
      elements.resize(elements.size() + last - first); //Exception 
      return copy (first, last, result); 
     } 

     typename TList <Item>::Type ::iterator begin() { return elements.begin(); } 
}; 

しかし、コピー操作中に

int main() 
{ 
    Cont <double> cont; 
    cont.push_back(1); 
    cont.push_back(2); 

    TList <double>::Type v; 
    v.push_back(3); 
    v.push_back(4); 
    cont.copy(v.begin(), v.end(), cont.begin()); //Exception 
    cont.copy(v.begin(), v.end(), cont.end()); //Exception 

    return 0; 
} 

私のテストコードでプログラムが実行時例外が発生します。エラーを見つけるのを助けてくれますか?

Exception: Vector iterator + offset out of range... 
+0

-1:あなたは、デバッガでコードをステップ実行しようとしたことがありますか?または、トレースステートメントを追加してキー変数の値を決定しますか? –

+0

これは貴重なコードです。それはなんのためですか? –

+0

@Space:私のC++の学習でのみテストします... – Johnas

答えて

7

式:

elements.size() + last - first 

は以下のように評価される:第一の加算の結果は、(デバッグモードで)例外をトリガベクトルの境界を超えてイテレータ、あろう

(elements.size() + last) - first 

。あなたはこれを試みることができる:

elements.size() + (last - first) 

以上のSTLのようなアプローチ:

elements.size() + std::distance(first, last) 
+0

ありがとうございましたが、別の問題があります:リターンコピー(最初、最後、結果)スタックオーバーフローの結果。どうして? – Johnas

+1

@Johnas:その行はあなたの 'copy'メソッドを呼び出します。その結果、無限の再帰が終わります。 'return std :: copy(first、last、result)'のような関数を明示的に記述する必要があります。 –

+0

もう一度、アドバイスが本当に私を助けました。 – Johnas

0

問題は、あなたのcopy方法は、それによってあなたが無効にそれを渡されたイテレータを作り、ベクトルのサイズを変更することに起因します。

+0

私はそれがここの問題だとは思わない。 OPのコードスニペットを信じる場合、 'resize'を実行する行で例外が発生します。 –

+0

@Oli:私もそれを理解しました。新しい範囲が古いものよりも大きければ、私は答えを残します。 –