سؤال

ولقد كان منذ بعض الوقت وأضاف البصرية ستوديو الدعم لتمديد 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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top