How to write a class capable of foreach

It has been some time since Visual Studio added support for the foreach extension, which works like

vector<int> v(3)
for each (int i in v) {
  printf("%d\n",i);
}

I want to know how to make any class capable of using foreach. Do I need to implement some kind of interface?

+5
source share
4 answers

for each in VC ++, if used in an unmanaged class:

for each (T x in xs)
{
    ...
}

is just syntactic sugar for this:

for (auto iter = xs.begin(), end = xs.end(); iter != end; ++iter)
{
     T x = *iter;
}

Where automeans that the type of the variable is inferred automatically from the type of the initializer.

In other words, you need to provide methods begin()and end()in your class that will return the input iterators and complete for it.

, istream :

#include <istream>
#include <iostream>
#include <fstream>
#include <string>


class lines
{
public:

    class line_iterator
    {
    public:

        line_iterator() : in(0)
        {
        }

        line_iterator(std::istream& in) : in(&in)
        {
            ++*this;
        }

        line_iterator& operator++ ()
        {
            getline(*in, line);
            return *this;
        }

        line_iterator operator++ (int)
        {
            line_iterator result = *this;
            ++*this;
            return result;
        }

        const std::string& operator* () const
        {
            return line;
        }

        const std::string& operator-> () const
        {
            return line;
        }

        friend bool operator== (const line_iterator& lhs, const line_iterator& rhs)
        {
            return (lhs.in == rhs.in) ||
                   (lhs.in == 0 && rhs.in->eof()) ||
                   (rhs.in == 0 && lhs.in->eof());
        }

        friend bool operator!= (const line_iterator& lhs, const line_iterator& rhs)
        {
            return !(lhs == rhs);
        }

    private:

        std::istream* const in;
        std::string line;
    };


    lines(std::istream& in) : in(in)
    {
    }

    line_iterator begin() const
    {
        return line_iterator(in);
    }

    line_iterator end() const
    {
        return line_iterator();
    }

private:

    std::istream& in;
};


int main()
{
    std::ifstream f(__FILE__);
    for each (std::string line in lines(f))
    {
        std::cout << line << std::endl;
    }
}

, line_iterator , , for each; , , , , , STL, , std::for_each, std::find ..

+10

std::for_each

+1
,

foreach ++. #. , , STL / Boost foreach. , ?

0

IEnumerable foreach

-2
source

All Articles