Как записать класс, способный к foreach

Я стал здесь опаздывающим, но возвращающийся к исходному вопросу, почему не просто используют lookarounds?

Pattern p = Pattern.compile("(?<=\\w)(?=\\W)|(?<=\\W)(?=\\w)");
System.out.println(Arrays.toString(p.split("'ab','cd','eg'")));
System.out.println(Arrays.toString(p.split("boo:and:foo")));

вывод:

[', ab, ',', cd, ',', eg, ']
[boo, :, and, :, foo]

РЕДАКТИРОВАНИЕ: То, что Вы видите выше, - то, что появляется на командной строке, когда я выполняю тот код, но я теперь вижу, что это немного сбивает с толку. Трудно отслеживать, которых запятые являются частью результата и которые были добавлены Arrays.toString(). Подсветка синтаксиса SO не помогает также. В надежде на то, чтобы заставлять выделение работать с меня вместо против меня, вот то, как те массивы посмотрели бы он, я объявлял их в исходном коде:

{ "'", "ab", "','", "cd", "','", "eg", "'" }
{ "boo", ":", "and", ":", "foo" }

я надеюсь, что это легче считать. Спасибо за предостережение, @finnw.

5
задан Pavel Minaev 26 October 2009 в 18:02
поделиться

4 ответа

для каждого оператора в VC ++ при использовании на неуправляемый класс:

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 на самом деле несколько больше минимума, необходимого для для каждой ; однако это минимальная реализация, которая соответствует требованиям итератора ввода, и, следовательно, этот класс также можно использовать со всеми алгоритмами STL, которые работают с итераторами ввода, такими как std :: for_each , std :: найдите и т. д.

#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 на самом деле несколько больше, чем минимум, необходимый для для каждого ; однако это минимальная реализация, которая соответствует требованиям итератора ввода, и, следовательно, этот класс также можно использовать со всеми алгоритмами STL, которые работают с итераторами ввода, такими как std :: for_each , std :: найдите и т. д.

#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 на самом деле несколько больше, чем минимум, необходимый для для каждого ; однако это минимальная реализация, которая соответствует требованиям итератора ввода, и, следовательно, этот класс также можно использовать со всеми алгоритмами STL, которые работают с итераторами ввода, такими как std :: for_each , std :: найдите и т. д.

10
ответ дан 14 December 2019 в 01:11
поделиться

Ваш класс должен унаследовать IEnumerable для использования foreach

-2
ответ дан 14 December 2019 в 01:11
поделиться

Насколько мне известно, foreach не является частью языка C ++. Хотя это на C #. Кроме того, я думаю, что STL и / или Boost имеют метод foreach. Возможно, вы думаете об этом?

0
ответ дан 14 December 2019 в 01:11
поделиться

Вы можете использовать этот

std :: for_each

1
ответ дан 14 December 2019 в 01:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: