Wie eine Klasse schreiben fähig ist foreach
-
06-07-2019 - |
Frage
Es ist schon eine Weile her, seit Visual Studio Unterstützung für eine foreach-Erweiterung hinzugefügt, die wie
funktionierenvector<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?
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