Frage

Es ist schon eine Weile her, seit Visual Studio Unterstützung für eine foreach-Erweiterung hinzugefügt, die wie

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

Ich möchte wissen, wie jede Klasse in der Lage zu machen foreach zu verwenden. Brauche ich eine Schnittstelle zu implementieren?

War es hilfreich?

Lösung

for each Anweisung in VC ++, wenn sie auf einer nicht-verwalteten Klasse verwendet:

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

ist nur syntaktischer Zucker für diese:

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

Wo auto bedeutet, dass Variablentyp von der Art des initializer automatisch abgeleitet wird.

Mit anderen Worten, Sie müssen begin() und end() Methoden auf Ihrer Klasse schaffen, zurückkehren würde beginnen und Eingabe Iteratoren zu Ende für sie.

Hier ist ein Beispiel von Klasse, die ein istream wickelt und ermöglicht es Ihnen, alle Linien in ihr iterieren:

#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;
    }
}

Beachten Sie, dass die Umsetzung von line_iterator ist tatsächlich etwas größer als das Minimum von for each benötigt; ist es jedoch die minimale Umsetzung, die InputIterator Anforderungen entspricht, und somit ist diese Klasse auch verwendbar mit allen STL-Algorithmen, die bei der Eingabe Iteratoren arbeiten, wie std::for_each, std::find etc.

Andere Tipps

Sie können dieses verwenden,

std::for_each

foreach ist nicht Teil der Sprache C ++, soweit ich weiß. Es ist in obwohl C #. Außerdem glaube ich, STL und / oder Erhöhung hat eine foreach-Methode. Vielleicht sind Sie, dass man denken?

sollte Ihre Klasse erben IEnumerable foreach verwenden

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top