我正在尝试编写一个类似于迭代器的STL,它将通过跳过每个其他字符来迭代字符串。但是,我遇到了许多不同的奇怪的C ++错误,我无法理解。
我的代码是:
#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:
...
有没有其他方法可以做这样的事情(也就是说,在字符串类上提供一个新的迭代器)而不将迭代器存储在我的类中作为迭代器?我已经在线编写了许多不同代码清单中的这个类,因此语义可能并不完美。
非常感谢有关解决此迭代器问题的任何帮助。
答案 0 :(得分: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++()
应该返回对递增的迭代器的引用,而不是对它所指向的容器的引用。