foreachが可能なクラスを書く方法
-
06-07-2019 - |
質問
Visual Studioがforeach拡張機能のサポートを追加してからしばらく経ちました
vector<int> v(3)
for each (int i in v) {
printf("%d\n",i);
}
クラスがforeachを使用できるようにする方法を知りたい。いくつかのインターフェースを実装する必要がありますか?
解決
非マネージクラスで使用する場合の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
の実装は、実際には各
に必要な最小値よりもいくらか大きいことに注意してください。ただし、入力イテレータの要件に準拠する最小の実装であるため、このクラスは、 std :: for_each
、 stdなど、入力イテレータで動作するすべてのSTLアルゴリズムでも使用できます。 :find
など。
他のヒント
これを使用できます
std :: for_each
foreachは、私の知る限りC ++言語の一部ではありません。ただし、C#です。また、STLやBoostにはforeachメソッドがあると思います。おそらくあなたはそれについて考えていますか?
クラスはforeachを使用するためにIEnumerableを継承する必要があります
所属していません StackOverflow