Բազմաթիվ ընթերցողների խնդրանքով այս
գրառումը նվիրում եմ Քիմ Քարդաշյանին։
C++11 լեզվում ներմուծված է նոր `for` հրամանը (range-based for loop), որը հնարավորություն է տալիս իտերացիա կատարել օբյեկտի `begin()`֊ից `end()` միջակայքում։ Օգտագործելով այդ `for` հրամանը, ուզում եմ հերթականությամբ թվարկել `ifstream` հոսքի նիշերը։
Ավելի պարզ ասած՝ ուզում եմ գրել այսպիսի մի կոդ․
գրառումը նվիրում եմ Քիմ Քարդաշյանին։
// ...
std::ifstream inp(name);
// ...
for( char c : obj )
std::cout << c;
// ...
Որտեղ `obj`-ը պիտի ստացվի `inp`֊ի հետ ինչ֊որ մանիպուլյացիաների արդյունքում։Նոր `for` հրամանն օգտագործելու համար նրան տրվող օբյեկտը (որով պետք է իտերացիա կատարվի), պետք է ունենա `begin()` և `end()` մեթոդները։ Մի քիչ քչփորելուց հետո պատրաստեցի `IterableFile` դասը, որն ընդլայնում է `ifstream`-ը՝ ավելացնելով ֆայլի սկզբի հետ կապված իտերատորը վերադարձնող `begin()` մեթոդը և դատարկ իտերատոր վերադարձնող `end()` մեթոդը։
class IterableFile : public std::ifstream {
public:
IterableFile( const char* name )
: std::ifstream{name}
{
// պահպանել բացատանիշերը
unsetf(std::ios_base::skipws);
}
std::istream_iterator<char> begin()
{
// սկսել ֆայլի սկզբից
clear(); seekg(0, std::ios::beg);
return std::istream_iterator<char>(*this);
}
const std::istream_iterator<char> end()
{
return std::istream_iterator<char>();
}
};
`IterableFile` դասի նմուշն արդեն կարելի է օգտագործել `for` իտերատորի մեջ, օրինակ, այսպես․
IterableFile fin("ex0.cpp");
for( char c : fin )
std::cout << c;
fin.close();
Շատ հարմար կլիներ, եթե նույն էֆեկտը ստանայի առանց նոր դաս գրելու, միայն STL֊ի հնարավորություններով, բայց կարծես թե դա չի ստացվում։ (Հաստատ չեմ կարող ասել։)
No comments:
Post a Comment