这只是一个玩具。
它包括一个基于生成器的文件(我发现它很容易编写),以及一个将生成器转换为迭代器的半工作适配器。
在这种情况下,生成器是一个函子,它接受一个 lambda,并将该 lambda 传递给迭代的事物并返回 true,或者返回 false。它形成了一个非常短的循环:
while( gen( [&]( std::string line ) {
// code using line goes here
} ) ); // <- notice that this is an empty while loop that does stuff
但你不能使用它。(这个设计的灵感来自于 python 生成器,老实说,我发现它比 C++ 迭代器更自然地处理多种问题,包括从文件中读取)。
adpator 接受这个生成器并将其变成一个迭代器,所以你可以将它传递给for_each
.
重点是您的问题本身是空洞的,因此我建议不要做一些明显的事情(转到,或直接for_each
在 istream 迭代器上使用),而是要搞乱一些迟钝和不同的事情。:)
Line 生成器又好又短:
struct LineGenerator {
LineGenerator(std::ostream& os_):os(&os_) {}
std::ostream* os;
template<typename F>
bool operator()(F&& func) {
std::string s;
bool bRet = std::getline( *os, s );
if (!bRet) return false;
std::forward<F>(func)(s);
return true;
}
};
另一方面,适配器非常混乱:(未经测试)
template<typename Generator>
struct generator_iterator {
typedef generator_iterator<Generator> my_type;
typedef typename std::decay< decltype( std::declval<Generator>()() ) >::type value_type;
Generator g;
bool bDone;
value_type val;
generator_iterator( Generator g_ ):g(g_), bDone(false) {
next();
}
generator_iterator(): bDone(true) {}
private:
void next() {
if (bDone) return;
bDone = g(val);
}
public:
generator_iterator& operator++() {
next();
return *this;
}
value_type operator*() {
return val;
}
const value_type operator*() const {
return val;
}
value_type* operator->() {
return &val;
}
value_type const* operator->() const {
return &val;
}
bool operator==( my_type const& o ) {
if (bDone != o.bDone) return false;
if (!bDone && !o.bDone) return true;
return false;
}
};
template<typename Generator>
generator_iterator<Generator> make_gen_it( Generator&& g ) {
return generator_iterator<Generator>( std::forward<Generator>(g) );
}
template<typename Generator>
generator_iterator<Generator> make_end_gen_it() {
return generator_iterator<Generator>();
}
我希望这很有趣!