你如何重写带有副作用的C ++ empty if语句

时间:2015-08-28 20:38:52

标签: c++

我的代码可以执行以下操作:

//datareader.cpp
if (populateFoo(dataReader, foo))
else {
   // Do other things with the reader.
}

//foo.cpp
bool populateFoo(const DataReader &dataReader, Foo &foo)
{
   if (dataReader.name() == "bar") {
      foo.bar() = dataReader.value();
      return true;
   } // More similar checks.
   return false;
}

我觉得有条件有副作用的if语句会产生误导。但是,我无法将populateFoo函数的主体移动到datareader.cpp中。有没有一个很好的方法来重构这个代码,所以我们摆脱这个误导if语句,而不重复populateFoo()的主体?

6 个答案:

答案 0 :(得分:4)

你对局部变量有强烈的仇恨吗?如果不是:

bool populated = populateFoo(dataReader, foo);

if (populated)
{
  // Do things
}
else 
{
  // Do other things
}

编译器几乎肯定会发出完全相同的代码,因此性能不应成为问题。这是最终的可读性/风格选择。

答案 1 :(得分:2)

显而易见的解决方案似乎是存储populateFoo的结果并使用它来确定populateFoo是否成功:

bool fooPopulated = populateFoo(dataReader, Foo);
if (!fooPopulated)
    //Do other things with reader.

然而,我发现原始版本难以理解,而且修改价值并在同一行中测试修改成功是一个相当成熟的做法。但是,我会将其更改为:

if (!populateFoo(dataReader, Foo)
    //Do other things with reader.

答案 2 :(得分:1)

怎么样:

if (!populateFoo(dataReader, foo)) {
    // Do other things with the reader.
}

编辑:问题的标题表明,if声明是空的,这会让你烦恼,但身体似乎更多的是副作用是关注点。我认为在C ++中,if语句中的条件有副作用,但如果你想避免这种情况,这将无法解决你的问题。

答案 3 :(得分:1)

有副作用的条件很常见 - 考虑调用C API并检查其返回代码是否有错误。

通常情况下,只要它没有埋没在一个复杂的表达中,偶然的旁观者可能会错过它,我不打算做特别的重构,但是,如果你想让它更清楚(或记录什么返回值是,在布尔值的情况下特别有用)只需将它分配给分支之前的变量 - 或者甚至只是一些注释可能有帮助。

答案 4 :(得分:0)

您可以将populateFoo函数拆分为两个,检查条件的const检查函数(shouldPopulateFoo)和执行实际修改的另一个非const函数(populateFoo) :

//datareader.cpp
if (shouldPopulateFoo(dataReader)) {
    populateFoo(dataReader, foo);
}
else {
    // Do other things with the reader.
}

//foo.cpp
bool shouldPopulateFoo(const DataReader &dataReader) /* const */
{
   return (dataReader.name() == "bar");
}

void populateFoo(const DataReader &dataReader, Foo &foo) /* non-const */
{
    assert(shouldPopulateFoo(dataReader));
    foo.bar = dataReader.value();
}

请注意,将这些函数用作类方法时,可以声明检查函数const。

答案 5 :(得分:0)

怎么样:

if (populateFoo(dataReader, foo) == false) {
// Do other things with the reader.
}

它非常易读,我经常看到代码,其中函数的返回值是信号,以便调用者在调用者中进行分支。带有else空格的if块比if ()内的副作用更让我烦恼。有一种反向逻辑感,这种逻辑总是不太可读。