对于循环与使用相对较旧的编译器的标准库算法

Kad*_*mir 4 c++ algorithm c++11

我知道当代码中没有任何令人困惑的for循环时,代码会更好.在可能的情况下重用标准库算法总是好的.但是,我发现迭代器和算法的语法看起来真的很混乱.

我想从我当前的项目中给出一个真实的例子:我想将内容复制vector<vector<QString>> invector<QVariant> out.我看不出以下区别:

for (int i = 0; i < in[0].size(); i++ ) 
{ 
    if(in[0][i].isNull() || in[0][i].isEmpty() ) 
        out[i] = "NONE";
    else
        out[i] = in[0][i];
}
Run Code Online (Sandbox Code Playgroud)

然后:

std::transform(in[0].begin(), in[0].end(), out.begin(), [](const QString& a)->QVariant{
    if(a.isNull() || a.isEmpty() ) 
        return "NONE";
    else
        return a;
}); 
Run Code Online (Sandbox Code Playgroud)

由于我们有visual studio 2012,我甚至必须输入我的lambda的返回值.使用范围之后:

in[0].map!( a => a.isNull() || a.isEmpty() ? "NONE" : a ).copy(out);
Run Code Online (Sandbox Code Playgroud)

在D语言中,我根本无法忍受std::transform上面的代码.我甚至不确定它是否比基本for循环更好.我的问题是:使用std::transform上面的代码比for循环好吗?

Jer*_*fin 8

至少在我看来,这里的主要问题是,这transform只是工作的错误工具.

你要做的就是做什么std::replace_copy_if,所以(毫不奇怪)它做得更整齐.

我没有手头的机器上安装Qt的,所以我把免去您的自由QVariantQString代码只是一个std::vector<std::string>,但我相信同样的基本思路应与Qt的类型也同样适用.

#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <string>

int main() {   
    std::vector<std::string> input { "one", "two", "", "three" };
    std::vector<std::string> output;

    // copy input to output, replacing the appropriate strings:
    std::replace_copy_if(input.begin(), input.end(),
                         std::back_inserter(output),
                         [](std::string const &s) { return s.empty(); }, 
                         "NONE");

    // and display output to show the results:
    std::copy(output.begin(), output.end(),
              std::ostream_iterator<std::string>(std::cout, "\n"));
}
Run Code Online (Sandbox Code Playgroud)

目前,这只是替换空字符串NONE,但添加空检查应该是非常简单的(isNull当然,有一种类型是有意义的).

根据上面的数据,我得到了你可能期望的结果:

one
two
NONE
three
Run Code Online (Sandbox Code Playgroud)

不过,我应该补充一点,即使这显然是非常冗长的.当我们至少将范围添加到标准库时,这将是很好的,所以(例如)input.begin(), input.end()可以用just替换input.结果仍然可能不会像你给出的D代码那样简洁,但至少它会稍微减少冗长(同样适用于大多数其他算法).

如果您关心这一点,那么range您可能需要查看几个库 - 一个Boost Range,以及(在我看来更有趣)Eric Neibler的范围库.