如何写一个能够foreach的类

时间:2009-10-26 17:25:53

标签: c++ visual-studio iterator foreach

自从Visual Studio添加了对类似

的foreach扩展的支持以来,已经有一段时间了
vector<int> v(3)
for each (int i in v) {
  printf("%d\n",i);
}

我想知道如何使任何类能够使用foreach。我需要实现一些接口吗?

4 个答案:

答案 0 :(得分:10)

VC ++中的

for each语句,在非托管类上使用时:

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

只是语法糖:

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

其中auto表示从初始化程序的类型自动推导出变量类型。

换句话说,您需要在类上提供begin()end()方法,以便为它返回开始和结束输入迭代器。

以下是包装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_eachstd::find等。

答案 1 :(得分:1)

您可以使用此

std::for_each

答案 2 :(得分:0)

据我所知,foreach不是C ++语言的一部分。它在C#中。另外,我认为STL和/或Boost有一个foreach方法。也许你正在考虑那个?

答案 3 :(得分:-2)

您的类应继承IEnumerable以使用foreach