【问题标题】:std::transform using C++0x lambda expressionstd::transform 使用 C++0x lambda 表达式
【发布时间】:2011-04-22 13:38:45
【问题描述】:

这是如何在 C++0x 中完成的?

std::vector<double> myv1;
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
               std::bind1st(std::multiplies<double>(),3));

原始问题和解决方案是here

【问题讨论】:

  • ....这是从其他帖子中获取的吗? stackoverflow.com/questions/3885095/…
  • @ianmac45 - 是的,我在上面链接到这个
  • @ianmac45 - 我的错,这是为了全面披露而进行的编辑
  • 为什么不只是for_each(begin(myv1), end(myv1), [](double&amp; a) { a *= 3; }
  • @Dario - for_each 不修改元素 - 我尝试将此作为原始 q 的解决方案 - 请参阅 stackoverflow.com/questions/662845/…

标签: c++ stl c++11 transform


【解决方案1】:
std::transform(myv1.begin(), myv1.end(), myv1.begin(), 
   [](double d) -> double { return d * 3; });

【讨论】:

  • -&gt; double 是不必要的;它会自动推断出来。
  • @potato - 它应该是,但当前的编译器有时会忽略这个事实。最好一直把它放进去。
  • 另一种方法是:std::transform(myv1.begin(), myv1.end(),myv1.begin(),myv1.end(), std::bind(std::multiplies&lt;double&gt;(),_1,3));
【解决方案2】:

在 C++ 中为这些情况使用该函数样式的主要原始动机是“啊啊!迭代器循环!”,而 C++0x 使用基于范围的 for 语句消除了这种动机。我知道问题的一部分是找出 lambda 语法,但我认为答案是“如何在 C++0x 中完成?”是:

for(double &a : myv1) { a *= 3; }

那里没有实际的函数对象,但如果它有帮助,您可以假装{ a *= 3; } 是高度缩写的 lambda。尽管标准草案根据等效的for 循环定义了基于范围的 for,但对于可用性而言,无论哪种方式都是一样的。

【讨论】:

  • 啊,是的。我通常会忘记这一点,因为我不使用支持它的编译器。 :( 绝对是最好的解决方案。
  • 这个构造的名称是什么?我仍然不熟悉 C++0x 中的内容。
  • “基于范围的 for 语句”,n3090 中的 6.5.4。添加到答案中。
  • 汤森。我认为它被称为“基于范围的for循环”。在 Java 中,同样的结构称为 foreach =/
【解决方案3】:

照达里奥所说的去做:

for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; });

for_each 被允许修改元素,说不能是一个神话。

【讨论】:

  • +1 因为这在原始问题中似乎更适合我
  • +1 表示“for_each 允许修改元素”。几年前,我参加了一场非常激烈的辩论。
【解决方案4】:

使用可变的方式,我们可以使用for_each直接通过引用更新序列元素。

for_each(begin(myv1), end(myv1), [](double& a) { a *= 3; });


是否真的允许for_each 修改元素存在一些争论,因为它被称为“非变异”算法。

这意味着for_each 不允许更改它所操作的序列(指的是序列结构的更改 - 即使迭代器无效)。这并不意味着我们不能像往常一样修改向量的非常量元素 - 结构本身不会受到这些操作的影响。

【讨论】:

    【解决方案5】:

    像这样:

    vector<double> myv1;
    transform(myv1.begin(), myv1.end(), myv1.begin(), [](double v)
    {
        return v*3.0;
    });
    

    【讨论】:

    • 我想每个人都是他自己的。我赶紧指出我的 正确的格式。 :)
    【解决方案6】:

    我正在使用支持 C++11 绑定适配器的 VS2012。要绑定二元函数的第一个元素(如 bind1st 那样),您需要添加一个 _1(占位符参数)。需要包含绑定的功能。

    using namespace std::placeholders;
    std::transform( myv1.begin(), myv1.end(), myv1.begin(),
                     std::bind( std::multiplies<double>(),3,_1));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 2023-01-20
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      相关资源
      最近更新 更多