كيفية كتابة فئة قادرة على foreach
-
06-07-2019 - |
سؤال
ولقد كان منذ بعض الوقت وأضاف البصرية ستوديو الدعم لتمديد foreach التي تعمل مثل
vector<int> v(3)
for each (int i in v) {
printf("%d\n",i);
}
وأريد أن أعرف كيفية جعل أي فئة قادرة على استخدام foreach. هل أنا بحاجة لتنفيذ بعض اجهة؟
المحلول
وبيان for each
في 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
هو في الواقع إلى حد ما أكبر من الحد الأدنى المطلوب من قبل for each
. ومع ذلك، فإنه هو الحد الأدنى للتنفيذ الذي يتوافق مع متطلبات إدخال مكرر، وبالتالي هذه الفئة هي أيضا صالحة للاستعمال مع جميع خوارزميات STL التي تعمل على المكررات المدخلات، مثل std::for_each
، std::find
الخ.
نصائح أخرى
ويمكنك استخدام هذا
وstd::for_each
وforeach ليست جزءا من لغة C ++ بقدر ما أعرف. انها في C # بالرغم من ذلك. أيضا، وأعتقد أن STL و / أو الدافع لديه طريقة foreach. ربما كنت تفكر في ذلك؟
وصفك أن يرث IEnumerable استخدام foreach