c++11 foreach 语法和自定义迭代器

发布于 2024-12-07 02:33:29 字数 696 浏览 1 评论 0原文

我正在为一个容器编写一个迭代器,用于代替 STL 容器。目前,STL 容器在许多地方都使用 c++11 foreach 语法< /a> 例如:for(auto &x: C)。我们需要更新代码以使用包装 STL 容器的自定义类:

template< typename Type>
class SomeSortedContainer{
    std::vector<typename Type> m_data; //we wish to iterate over this
    //container implementation code
};    
class SomeSortedContainerIterator{
    //iterator code
};

How do I get auto to use the正确的迭代器用于自定义容器,以便能够通过以下方式调用代码?:

SomeSortedContainer C;
for(auto &x : C){
    //do something with x... 
}

一般来说,什么是需要确保 auto 对类使用正确的迭代器?

I am writing an iterator for a container which is being used in place of a STL container. Currently the STL container is being used in many places with the c++11 foreach syntax eg: for(auto &x: C). We have needed to update the code to use a custom class that wraps the STL container:

template< typename Type>
class SomeSortedContainer{
    std::vector<typename Type> m_data; //we wish to iterate over this
    //container implementation code
};    
class SomeSortedContainerIterator{
    //iterator code
};

How do I get auto to use the correct iterator for the custom container so the code is able to be called in the following way?:

SomeSortedContainer C;
for(auto &x : C){
    //do something with x... 
}

In general what is required to ensure that auto uses the correct iterator for a class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

平定天下 2024-12-14 02:33:29

为了能够使用基于范围的 for,您的类应该提供 const_iterator begin() const 和 const_iterator end() const 成员。您还可以重载全局 begin 函数,但我认为拥有成员函数更好。还建议使用 iterator begin()const_iterator cbegin() const,但不是必需的。如果您只想迭代单个内部容器,那非常简单:

template< typename Type>
class SomeSortedContainer{

    std::vector<Type> m_data; //we wish to iterate over this
    //container implementation code
public:
    typedef typename std::vector<Type>::iterator iterator;
    typedef typename std::vector<Type>::const_iterator const_iterator;

    iterator begin() {return m_data.begin();}
    const_iterator begin() const {return m_data.begin();}
    const_iterator cbegin() const {return m_data.cbegin();}
    iterator end() {return m_data.end();}
    const_iterator end() const {return m_data.end();}
    const_iterator cend() const {return m_data.cend();}
};    

如果您想迭代任何自定义内容,您可能必须将自己的迭代器设计为容器内的类。

class const_iterator : public std::iterator<random_access_iterator_tag, Type>{
    typename std::vector<Type>::iterator m_data;
    const_iterator(typename std::vector<Type>::iterator data) :m_data(data) {}
public:
    const_iterator() :m_data() {}
    const_iterator(const const_iterator& rhs) :m_data(rhs.m_data) {}
     //const iterator implementation code
};

有关编写迭代器类的更多详细信息,请参阅我的回答

To be able to use range-based for, your class should provide const_iterator begin() const and const_iterator end() const members. You can also overload the global begin function, but having a member function is better in my opinion. iterator begin() and const_iterator cbegin() const are also recommended, but not required. If you simply want to iterate over a single internal container, that's REALLY easy:

template< typename Type>
class SomeSortedContainer{

    std::vector<Type> m_data; //we wish to iterate over this
    //container implementation code
public:
    typedef typename std::vector<Type>::iterator iterator;
    typedef typename std::vector<Type>::const_iterator const_iterator;

    iterator begin() {return m_data.begin();}
    const_iterator begin() const {return m_data.begin();}
    const_iterator cbegin() const {return m_data.cbegin();}
    iterator end() {return m_data.end();}
    const_iterator end() const {return m_data.end();}
    const_iterator cend() const {return m_data.cend();}
};    

If you want to iterate over anything custom though, you'll probably have to design your own iterators as classes inside your container.

class const_iterator : public std::iterator<random_access_iterator_tag, Type>{
    typename std::vector<Type>::iterator m_data;
    const_iterator(typename std::vector<Type>::iterator data) :m_data(data) {}
public:
    const_iterator() :m_data() {}
    const_iterator(const const_iterator& rhs) :m_data(rhs.m_data) {}
     //const iterator implementation code
};

For more details on writing an iterator class, see my answer here.

残疾 2024-12-14 02:33:29

您有两种选择:

  • 提供名为 beginend 的成员函数,可以像 C.begin()C 一样调用它们。结束();
  • 否则,您提供名为 beginend 的自由函数,可以使用依赖于参数的查找或在命名空间 std 中找到这些函数,并且可以调用例如begin(C)end(C)

You have two choices:

  • you provide member functions named begin and end that can be called like C.begin() and C.end();
  • otherwise, you provide free functions named begin and end that can be found using argument-dependent lookup, or in namespace std, and can be called like begin(C) and end(C).
旧话新听 2024-12-14 02:33:29

正如其他人所说,您的容器必须实现 begin()end() 函数(或者具有接受实例的全局或 std:: 函数)您的容器作为参数)。

这些函数必须返回相同的类型(通常是 container::iterator,但这只是一个约定)。返回的类型必须实现 operator*operator++operator!=

As others have stated, your container must implement begin() and end() functions (or have global or std:: functions that take instances of your container as parameters).

Those functions must return the same type (usually container::iterator, but that is only a convention). The returned type must implement operator*, operator++, and operator!=.

千纸鹤带着心事 2024-12-14 02:33:29

据我所知,SomeSortedContainer只需要提供begin()end()。这些应该返回一个符合标准的前向迭代器,在您的情况下是 SomeSortedContainerIterator,它实际上会包装一个 std::vector::iterator。对于符合标准,我的意思是它必须提供通常的增量和解引用运算符,而且还提供所有这些 value_typereference_type、... typedef,它们又由foreach 构造来确定容器元素的基础类型。但您可能只是从 std::vector::iterator 转发它们。

To my knowledge SomeSortedContainer just needs to provide begin() and end(). And these should return a standard compliant forward iterator, in your case SomeSortedContainerIterator, which would actually wrap a std::vector<Type>::iterator. With standard compliant I mean it has to provide the usual increment and dereferencing operators, but also all those value_type, reference_type, ... typedefs, which in turn are used by the foreach construct to determine the underlying type of the container elements. But you might just forward them from the std::vector<Type>::iterator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文