2017-02-04 1 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

어떤 import 문을 사용하고 있습니까? – awiebe

+0

@awiebe'iostream','vector','string','sstream'. – Jackson

+0

전체 소스에 대한 링크를 추가했습니다. – Jackson

답변

4

- 복사/이동 건설에 반복자는 여전히 이전 객체의 벡터를 가리 킵니다.

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 (들어, 사실); – Jackson

+0

@Jackson'WordCrawler wc = in'은'WordCrawler wc = WordCrawler (in)'을 의미합니다. –

관련 문제