「連結イテレータ」、つまり のint
s を反復するイテレータを作成していましたint**
。
そのコンストラクターには次が必要です。
T**
各サブ配列の先頭を表す の配列。T**
各サブ配列の終わりを表す の配列。
見よ、私はgoto
適切と思われる状況に出くわした.
しかし、私の中で何かが「NO!!」と叫びました。だから私はここに来て尋ねようと思った:
goto
このような状況は避けるべきですか?(そうすれば可読性が向上しますか?)
#include <algorithm>
template<class T>
class lazy_concat_iterator
{
// This code was meant to work for any valid input iterator
// but for easier reading, I'll assume the type is: T**
mutable T** m_endIt; // points to an array of end-pointers
mutable T** m_it; // points to an array of begin-pointers
mutable bool m_started; // have we started iterating?
mutable T* m_sub; // points somewhere in the current sub-array
mutable T* m_subEnd; // points to the end of the current sub-array
public:
lazy_concat_iterator(T** begins, T** ends)
: m_it(begins), m_endIt(ends), m_started(false) { }
void ensure_started() const
{
if (!m_started)
{
m_started = true;
INIT:
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub == m_subEnd) // End of this subarray?
{
++m_it;
++m_endIt;
goto INIT; // try next one <<< should I use goto here?
}
}
}
};
どのように使用できますか:
#include <vector>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
vector<char*> beginnings(argv, argv + argc);
vector<char*> endings;
for (int i = 0; i < argc; i++)
endings.push_back(argv[i] + strlen(argv[i]));
lazy_concat_iterator<char> it(&beginnings[0], &endings[0]);
it.ensure_started(); // 'it' would call this internally, when dereferenced
}