而带有逗号运算符的循环与重复的代码与“break;”



在阅读了关于 C/C++ 中逗号运算符的精彩答案(逗号运算符是做什么的 - 我使用相同的示例代码)之后,我想知道哪种是实现 while 循环的最易读、最易于维护、首选的方法。 特别是一个 while 循环,其条件取决于操作或计算,并且条件第一次可能为 false(如果循环总是至少通过一次,那么 do-while 将正常工作)。

逗号版本是首选吗? (每个答案怎么样,其余的可以通过相应的投票来投票?

实施简单

此代码具有重复的语句,这些语句(很可能)必须始终相同。

string s;
read_string(s);     // first call to set up the condition
while(s.len() > 5)  // might be false the first pass
{
   //do something
   read_string(s);  // subsequent identical code to update the condition
}

使用中断实现

string s;
while(1)                  // this looks like trouble
{
   read_string(s);
   if(s.len() > 5) break; // hmmm, where else might this loop exit
   //do something
}

使用逗号实现

string s;
while( read_string(s), s.len() > 5 ) 
{
   //do something
}

我会说以上都不是。我看到几个选择。它们之间的选择取决于您的实际约束。

一种可能性是,您有一个字符串,该字符串应始终具有一些最小长度。如果是这种情况,您可以定义体现该要求的类:

template <size_t min>
class MinString{
    std::string data;
public:
    friend std::istream &operator>>(std::istream &is, MinString &m) {
        std::string s;
        read_string(is, s); // rewrite read_string to take an istream & as a parameter
        if (s.length() >= min)
            m.data = s;
        else
            is.setstate(std::ios::failbit);
        return is;
    }
    operator std::string() { return data; }
    // depending on needs, maybe more here such as assignment operator
    // and/or ctor that enforce the same minimum length requirement
};

这会导致代码如下:

Minstring<5> s;
while (infile >> s)
    process(s);

另一种可能性是你有正常的字符串,但在某些情况下你需要执行一个必须至少 5 个字符。在这种情况下,强制应在函数而不是类型中。

bool read_string_min(std::string &s, size_t min_len) { 
    read_string(s);
    return s.length() >= min_len;
}

同样,有了这个,循环可以简单而干净:

while (read_string_min(s, 5))
    process(s);

也可以只编写一个返回读取长度的函数,并保留最小值的执行while 循环中的长度:

while (read_string(s) > 5)
    process(s);

有些人喜欢这样的想法是它更符合单一责任原则。IMO,"读取至少 5 个字符的字符串"完全符合单一责任的条件,所以它充其量只是一个薄弱的论点(但即使是这种设计仍然使编写代码变得容易干净)。

摘要:任何执行输入的内容都应隐式或显式提供某种方法来验证它是否正确读取了输入。只是尝试读取一些输入但没有提供成功/失败指示的东西只是一个糟糕的设计(正是你的read_string设计中的明显失败导致了你遇到的问题)。

对我来说,

第四种选择似乎更好:

string s;
while( read_string(s) && s.len() > 5 ) 
{
   //do something
}

相关内容

  • 没有找到相关文章

最新更新