C++ 变换和 lambda - 替换 for 循环

标签 c++ algorithm c++11 lambda

我想用 std::transform 替换 for 循环。由于我对算法和 lambda 函数缺乏经验,我想知道这是否是正确的方法

原始代码

for (size_t i=0; i < dataPhase.size(); ++i)
{
    dataPhase[i] = fmod(dataPhase[i], pi*1.00001);
}

使用 lambda 进行 std::transform

std::transform(dataPhase.begin(), dataPhase.end(), dataPhase.begin(), 
               [](double v){return fmod(v, pi*1.00001); }
);

我需要在这里捕获吗?

在这种使用索引的情况下,我可以做什么来替换 for 循环,如以下代码所示:

const int halfsize = int(length/2);
for (size_t i=0; i < length; ++i)
{
    axis[i] = int(i) - halfsize;
}

编辑: 我想扩展这个问题(如果允许的话)。

是否可以用不同的东西替换这种情况下的 for 循环

for(std::vector<complex<double> >::size_type i = 0; i != data.size(); i++) {
    dataAmplitude[i] = abs(data[i]);
    dataPhase[i]     = arg(data[i]);
}

这里不是修改原始 vector ,而是将其值用于两个不同的 vector 。

最佳答案

第 1 部分)

此处不需要捕获,因为您仅在 lambda 代码中使用参数 (v) 和全局变量 (pi)。

仅当 lambda 必须访问当前作用域中的变量(即在函数中声明的变量)时才需要捕获。您可以通过引用 (&) 或通过值 (=) 进行捕获。

下面是一个需要“通过引用捕获”的示例,因为“结果”是从 lambda 内部修改的(但它也捕获了“searchValue”):

size_t count(const std::vector<char>& values, const char searchValue)
{
 size_t result = 0;
 std::for_each(values.begin(), values.end(), [&](const char& v) {
  if (v == searchValue)
   ++result;
 });
 return result;
}

(在现实世界中,请使用 std::count_if() 甚至 std::count())

编译器为每个捕获 lamda 创建一个未命名仿函数(请参阅 this question )。函数的构造函数接受参数并将其存储为成员变量。因此,“按值捕获”始终使用定义 lambda 时元素所具有的值。

下面是编译器可以为我们之前创建的 lambda 生成的代码示例:

class UnnamedLambda
{
public:
 UnnamedLambda(size_t& result_, const char& searchValue_)
  : result(result_), searchValue (searchValue_)
 {}

 void operator()(const char& v)
 {
  // here is the code from the lambda expression
  if (v == searchValue)
   ++result;
 }

private:
 size_t& result;
 const char& searchValue;
};

我们的函数可以重写为:

size_t count(const std::vector<char>& values, const char searchValue)
{
 size_t result = 0;
 UnnamedLambda unnamedLambda(result, searchValue);
 for(auto it = values.begin(); it != values.end(); ++it)
  unnamedLambda(*it);
 return result;
}

第 2 部分)

如果您需要索引,请继续使用 for 循环。

std::transform 允许处理单个元素,因此不提供索引。还有一些其他算法,例如 std::accumulate,可以处理中间结果,但我不知道任何提供索引的算法。

关于C++ 变换和 lambda - 替换 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45051819/

相关文章:

c++ - 基类使用父类定义的类型

c++ - 将共享库的搜索路径更改为 Makefile 中提供的 rpath

c++ - 奇怪的 C++ 语法和 decltype

c++ - 从订购的容器中制作比较器

C++ 多线程

c++ - 使用以太网电缆在两台 Mac 之间自动传输文件?

algorithm - 每个元素重量相同的0-1背包是NP完全的吗?

c++ - C++ 中的抽象语法树表示

java - UVa 的扫雷 (10189)

python - 使用 numpy 的快速元素节点平均