我正在创建一个"连接迭代器",即一个迭代器,它将遍历ints中的s int**.
它的构造函数需要:
T**,表示每个子数组的开头.T**,表示每个子数组的结尾.瞧,我遇到了一个goto似乎合适的情况.
但是我内心的某些东西尖叫着"不!" 所以我以为我会来这里问:
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?
}
}
}
};
Run Code Online (Sandbox Code Playgroud)
你如何使用它:
#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
}
Run Code Online (Sandbox Code Playgroud)
CB *_*ley 11
是的,您可以而且应该避免goto,例如,此代码应该与您在INIT标签上执行的操作相同(这也适用于输入迭代器,这是一个"隐藏的要求",因为它不会取消引用,m_it并且m_endIt一旦条件有额外的时间与我以前的转型不同,我遇到了:
while ((m_subIt = *m_it) == (m_subEnd = *m_endIt))
{
++m_it;
++m_endIt;
}
Run Code Online (Sandbox Code Playgroud)
以前的回答尝试:
即使是一个永远的循环也会比一个更清晰,更整洁goto.它突出了明显的"永不终止"的可能性甚至更好.
for (;;)
{
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub != m_subEnd)
break;
++m_it;
++m_endIt;
}
Run Code Online (Sandbox Code Playgroud)
虽然我不明白为什么你需要分配到m_subEnd并m_subIt在循环中.如果不这样做,你可以将其重写为while循环:
while (*m_it == *m_endIt)
{
++m_it;
++m_endIt;
}
m_subIt = *m_it;
m_subEnd = *m_endIt;
Run Code Online (Sandbox Code Playgroud)
while (*m_it == *m_endIt)
{
++m_it;
++m_endIt;
}
m_sub = *m_it;
m_subEnd = *m_endIt;
Run Code Online (Sandbox Code Playgroud)