while while with逗号运算符与重复代码对话“break;”

时间:2016-03-11 16:25:39

标签: c++ c while-loop break comma-operator

在阅读了关于C / C ++(What does the comma operator do中的逗号运算符的一个很好的答案 - 我使用相同的示例代码)之后,我想知道哪个是最易读,可维护,首选的实现方式环。特别是一个while循环,其条件取决于操作或计算,条件可能是第一次错误(如果循环总是至少传递一次那么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
}

使用break

实现
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
}

2 个答案:

答案 0 :(得分:3)

我不会说上述情况。我看到了几个选择。它们之间的选择取决于你的实际约束。

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

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的设计明显失败导致你遇到的问题。)

答案 1 :(得分:0)

第四种选择对我来说似乎更好:

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