2014-04-10 73 views
-1

我試圖寫一個概念證明,像迭代器那樣通過跳過其他每個字符來遍歷字符串的STL。但是,我遇到了很多不同的奇怪的C++錯誤,我無法理解。自定義STL迭代器實現錯誤

我的代碼是:

#include<iostream> 
#include<string> 

using std::string; 

class TestIterator : public std::iterator<std::forward_iterator_tag, string> { 
private: 
    string::iterator _it; 

public: 
    TestIterator() {} 

    string& operator++() { 
    return _it + 2; 
    } 

    string& operator=(const string& other) { 
    _it = other; 
    } 
}; 

int main(int argc, char** argv) { 
    string a("123045678"); 
    TestIterator start = a.begin(); 
    TestIterator end = a.end(); 
    string b(start, end); 

    std::cout << b << std::endl; 

    return 0; 
} 

當我編譯它,我得到:

% g++ -std=gnu++0x test.cpp -o test 
test.cpp: In member function ‘std::string& TestIterator::operator++()’: 
test.cpp:14:16: error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >’ 
    return _it + 2; 
       ^
test.cpp: In member function ‘std::string& TestIterator::operator=(const string&)’: 
test.cpp:18:9: error: no match for ‘operator=’ (operand types are ‘std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}’ and ‘const string {aka const std::basic_string<char>}’) 
    _it = other; 
     ^
test.cpp:18:9: note: candidates are: 
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0, 
       from /usr/include/c++/4.8/bits/char_traits.h:39, 
       from /usr/include/c++/4.8/ios:40, 
       from /usr/include/c++/4.8/ostream:38, 
       from /usr/include/c++/4.8/iostream:39, 
       from test.cpp:1: 
/usr/include/c++/4.8/bits/stl_iterator.h:708:11: note: __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >& __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >::operator=(const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&) 
    class __normal_iterator 
     ^
/usr/include/c++/4.8/bits/stl_iterator.h:708:11: note: no known conversion for argument 1 from ‘const string {aka const std::basic_string<char>}’ to ‘const __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&’ 
/usr/include/c++/4.8/bits/stl_iterator.h:708:11: note: __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >& __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >::operator=(__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&&) 
/usr/include/c++/4.8/bits/stl_iterator.h:708:11: note: no known conversion for argument 1 from ‘const string {aka const std::basic_string<char>}’ to ‘__gnu_cxx::__normal_iterator<char*, std::basic_string<char> >&&’ 
test.cpp: In function ‘int main(int, char**)’: 
test.cpp:24:32: error: conversion from ‘std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}’ to non-scalar type ‘TestIterator’ requested 
    TestIterator start = a.begin(); 
           ^
test.cpp:25:28: error: conversion from ‘std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}’ to non-scalar type ‘TestIterator’ requested 
    TestIterator end = a.end(); 
          ^
In file included from /usr/include/c++/4.8/string:53:0, 
       from /usr/include/c++/4.8/bits/locale_classes.h:40, 
       from /usr/include/c++/4.8/bits/ios_base.h:41, 
       from /usr/include/c++/4.8/ios:42, 
       from /usr/include/c++/4.8/ostream:38, 
       from /usr/include/c++/4.8/iostream:39, 
       from test.cpp:1: 
/usr/include/c++/4.8/bits/basic_string.tcc: In instantiation of ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = TestIterator; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’: 
/usr/include/c++/4.8/bits/basic_string.h:1725:56: required from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct_aux(_InIterator, _InIterator, const _Alloc&, std::__false_type) [with _InIterator = TestIterator; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ 
/usr/include/c++/4.8/bits/basic_string.h:1746:58: required from ‘static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&) [with _InIterator = TestIterator; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ 
/usr/include/c++/4.8/bits/basic_string.tcc:229:49: required from ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = TestIterator; _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ 
test.cpp:26:22: required from here 
/usr/include/c++/4.8/bits/basic_string.tcc:128:12: error: no match for ‘operator==’ (operand types are ‘TestIterator’ and ‘TestIterator’) 
    if (__beg == __end && __a == _Alloc()) 
      ^
/usr/include/c++/4.8/bits/basic_string.tcc:128:12: note: candidates are: 
... 

有就是提供對串一個新的迭代任何其他方式做這樣的事情(類)而不在我的類中存儲將作爲迭代器的迭代器?我已經在線將許多不同的代碼清單拼湊起來,所以語義可能並不完美。

任何幫助解決這個迭代器問題將不勝感激。

+1

'_sBegin'等是'std :: string :: iterators',但是你的方法返回'string&'。這是行不通的,而且是編譯器告訴你的。 – juanchopanza

+0

澄清@juanchopanza的要點 - 字符串迭代器返回對字符串*元素*(例如'char')的引用。您正在返回對整個字符串的引用。 –

+2

你有沒有考慮過使用'boost :: iterator_facade'?它討論了大多數實現自己的迭代器的煩惱。 –

回答

0

STL迭代器由容器對象,從容器本身不構成創建:

int main(int argc, char** argv) { 
    string a("abcdefghijk"); 
    TestIterator start = a.begin(); //<----------- 
    TestIterator stop = a.end(); //<----------- 
    string b(start, stop); //<----------- 

    std::cout << b << std::endl; 

    return 0; 
} 

因此,新的迭代器必須能夠從string::iterator其中string::begin()收益構成。

STL迭代器本身沒有begin()end();這是集裝箱的工作。

operator++()應該返回對正在增加的迭代器的引用,而不是對它指向的容器的引用。

+0

謝謝,我開始更多地理解代碼中應該發生的事情。不過,我仍然看到新的變化帶來了一些神祕的新錯誤。你能看看我的編輯,看看我要去哪裏錯了嗎? – David

+0

堆棧溢出對於這些類型的東西可能很好,但是確保首先閱讀更多關於STL迭代器的信息。在你將自己的實現暴露在頭之前,它將更快地從大量教程中學習API。 – Suedocode