我应该避免“goto”在这样的情况下? [英] Should I avoid "goto" in situations like this?

查看:205
本文介绍了我应该避免“goto”在这样的情况下?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个连接迭代器,即迭代器将遍历 int s在 int **

I was making a "concatenating iterator", i.e. an iterator that would iterate over the ints in an int**.

其构造函数需要:


  • 数组 $
  • $ ,表示每个子数组的开头。 ,表示每个子数组的结尾。
  • An array of T**, representing the beginning of each sub-array.
  • An array of T**, representing the end of each sub-array.

Lo,看到我遇到了 goto 似乎是适当的。

Lo and behold, I ran across a situation where goto seemed to be appropriate.

但是我内心的东西尖叫着不!所以我想我会来这里问:

But something within me screamed "NO!!" so I thought I'd come here and ask:

#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
}


推荐答案

是的,你可以而且应该避免 goto ,例如这段代码应该从 INIT label(这也适用于输入迭代器,这是一个隐藏要求,因为它不引用 m_it m_endIt 一次满足条件的额外时间不像我以前的转换):

Yes, you can and should avoid goto, for example this code should do the equivalent for what yours does from the INIT label (this also works for input iterators which was a "hidden requirement" as it doesn't dereference m_it and m_endIt an extra time once the condition is met unlike my previous transformation):

while ((m_subIt = *m_it) == (m_subEnd = *m_endIt))
{
    ++m_it;
    ++m_endIt;
}






尝试:

即使是永远的循环也会比 goto

Even a forever loop would be clearer and neater than a goto. It highlights the obvious "never terminate" possibility even better.

    for (;;)
    {
        m_sub = *m_it;
        m_subEnd = *m_endIt;

        if (m_sub != m_subEnd)
            break;

        ++m_it;
        ++m_endIt;
    }

虽然我不明白为什么你需要分配 m_subEnd m_subIt 。如果你不能,你可以重写这个while循环:

Although I don't see why you need to assign to m_subEnd and m_subIt inside the loop. If you don't you can rewrite this as a while loop:

while (*m_it == *m_endIt)
{
    ++m_it;
    ++m_endIt;
}

m_subIt = *m_it;
m_subEnd = *m_endIt;

这篇关于我应该避免“goto”在这样的情况下?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆