我正在尝试学习C ++,并且希望更好地了解迭代器。为此,我尝试为自定义类(称为StrBlob
,它包含在美妙的C++ Primer中定义的字符串)编写与STL兼容的迭代器。最终,以下迭代器定义起作用了:
class StrBlob::iterator
: public std::iterator<std::input_iterator_tag, // iterator_category
std::string, // value_type
std::string, // difference_type
const std::string*, // pointer
std::string // reference
> {
public:
iterator() : curr(0) {}
iterator(StrBlob& a, size_t sz = 0) : wptr(a.data), curr(sz) {}
iterator& operator++(); // prefix operators
iterator& operator--();
iterator operator++(int); // postfix operators
iterator operator--(int);
std::string& operator*() const;
std::string* operator->() const;
bool operator==(const iterator& b) const { return curr == b.curr; }
bool operator!=(const iterator& b) const { return curr != b.curr; }
private:
std::shared_ptr<std::vector<std::string>> check(std::size_t,
const std::string&) const;
std::weak_ptr<std::vector<std::string>> wptr;
std::size_t curr;
};
最初,我花了很长时间尝试尝试自己设计具有正确类型定义的迭代器。这没有用,所以我只是向cppreference中提到的std::iterator
提供了一个继承。
我可以编写完全不继承的类吗?如果是这样,我将如何重写上面的代码?
(我试图了解Stackoverflow对有关迭代器设计的相关问题的答案,但对我来说这些答案有些抽象。)
答案 0 :(得分:2)
您的代码有错误,std::string
不是合适的差异类型(difference_type
是两个迭代器之间的差异,因此通常是std::ptrdiff_t
),std::string
也不合适引用类型(应为std::string&
)。
这是正确的typedef,您可以使用它们代替继承。
typedef std::input_iterator_tag iterator_category;
typedef std::string value_type;
typedef std::ptrdiff_t difference_type;
typedef std::string* pointer;
typedef std::string& reference;
答案 1 :(得分:1)
我可以编写完全不继承的类吗?如果是这样,我该如何重写上面的代码?
是的std::iterator
(在C ++ 17中已弃用)仅提供typedef。
因此,您可以自己添加这些typedef,而不必使用继承。
class StrBlob::iterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = std::string;
using difference_type = std::string;// should be `std::ptrdiff_t`
using pointer = const std::string*; // const should probably be dropped, unless you do const_iterator
using reference = std::string; // should be std::string&
// ...
};