2017-02-04 36 views
2

私は、スペース区切りの単語列を表すクラスを、それらの単語のベクトルとベクトルの反復子を介して表します。Visual StudioでのC++の `vector iterators incompatible`エラーのみ

class WordCrawler{ 
public: 
    WordCrawler(std::string, bool reversed=false); 
    WordCrawler& operator--(); 
    std::string operator* () const; 

    bool atBeginning() const; 
private: 
    std::vector<std::string> words; 
    std::vector<std::string>::iterator it; 
}; 

私はこの機能を使用して、逆の順序で単語をプリントアウトしようとしています:の

WordCrawler::WordCrawler(std::string in, bool reversed) { 
    std::istringstream iss(in); 
    std::string token; 
    while (std::getline(iss, token, ' ')) 
    { 
     words.push_back(token); 
    } 
    if (reversed) { 
     it = words.end(); 
    } else { 
     it = words.begin(); 
    } 
} 

残り:

void print_in_reverse(std::string in) { 
    WordCrawler wc = WordCrawler(in, true); 
    while (!wc.atBeginning()) { 
     --wc; 
     std::cout << *wc << " "; 
    } 
} 

が、私はこのコンストラクタで私のWordCrawlerオブジェクトを構築メンバ関数はかなり単純です:

/** 
True if pointer is at the beginning of vector 
*/ 
bool WordCrawler::atBeginning() const { 
    return it == words.begin(); 
} 

/** 
    Function that returns the string stored at the pointer's address 
*/ 
std::string WordCrawler::operator*() const { 
    return *it; 
} 

/** 
    Function that increments the pointer back by one 
*/ 
WordCrawler& WordCrawler::operator--() { 
    if (!atBeginning()) 
     --it; 
    return *this; 
} 

私はすべてXcodeとcpp.shでうまく動作していますが、Visual StudioではatBeginning()という機能でvector iterators incompatibleというランタイムエラーが発生します。私の前提は、コードが何らかの未定義の振る舞いに依存しているからですが、C++には比較的新しいので、どういうことがわかりません。

私はitは常にwordsベクトルのイテレータであることを知っている、と私はitが初期化された後wordsが変化しないことを知っているので、私は問題が何であるかわかりません。

完全なコードで:http://codepad.org/mkN2cGaM

+0

使用しているインポートステートメントは何ですか? – awiebe

+0

@awiebe 'iostream'、' vector'、 'string'、' sstream'です。 – Jackson

+0

フルソースへのリンクを追加しました。 – Jackson

答えて

4

あなたのオブジェクトが3件の違反のルールを持っている - コピー/移動の建設にイテレータはまだ古いオブジェクトのベクトルを指します。

WordCrawler wc = WordCrawler(in, true);は、この問題を引き起こすコピー/移動操作を指定しています。ほとんどのコンパイラはここでコピーを実行しますが、MSVCの古いバージョンは、とにかくデバッグモードでは動作しません。

これを正しく修正するには、クラス内のイテレータの代わりにインデックスを使用することをお勧めします。実際にイテレーターを使用したい場合は、独自のコピーコンストラクターと移動コンストラクターを実装する必要があります。

この行をWordCrawler wc(in, true);に変更すると、この特定のプログラムが修正される可能性がありますが、同じ問題がまだ潜んでいる可能性があります。後でさらに修正すると表示される可能性があります。

+0

それで 'WordCrawler wc(in、true);はすばやく修正されますか? –

+0

興味深い。私のフォワードバージョンでは、 'for(WordCrawler wc = in;!wc.reachedEnd(); wC++)'を使って、 'WordCrawler wc = in 'を使った黒いマジックC++型強制は' WordCrawler wc (in、true); 'だろうか? – Jackson

+0

@Jackson「WordCrawler wc = in」は、「WordCrawler wc = WordCrawler(in)」を意味します。 –

関連する問題