1

我收到这些错误。为什么?

在 /usr/include/c++/4.7/algorithm:63:0 中包含的文件中,来自 prog.cpp:2:/usr/include/c++/4.7/bits/stl_algo.h:在 '_OIter std::transform 的实例化中(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = __gnu_cxx::__normal_iterator >; _OIter = std::back_insert_iterator >; _UnaryOperation = main()::]': prog.cpp:10:98: 从这里需要 /usr/include/c++/4.7/bits/stl_algo.h:4951:2: 错误: 不匹配调用'(main ()::) (int&)' prog.cpp:10:64: 注意:候选者是:在 /usr/include/c++/4.7/algorithm:63:0 包含的文件中,来自 prog.cpp:2: /usr /include/c++/4.7/bits/stl_algo.h:4951:2: 注意: int (*)(int, int) /usr/include/c++/4.7/bits/stl_algo.h:4951:2: 注意: 候选需要 3 个参数,2 个提供 prog.cpp:10:79: 注意:main():: prog.cpp:10:79: 注意:

#include <algorithm>
#include <vector>

int main()
{
    std::vector<int> v {1, 2, 3, 4, 5, 6};
    std::vector<int> r;

    std::transform(v.begin(), v.end(), std::back_inserter(r), [] (int a, int b) { return a + b; });
}

此代码应该将每对数字相加并将其放入r向量中,但它不起作用。这是为什么?

4

1 回答 1

3

您已经选择了transform()在单个范围内工作的重载 - 因此期望提供一元仿函数作为最后一个参数。

如果您想要在两个范围内工作(也许是同一范围的两个“副本”?),那么您应该这样做:

std::transform(v.begin(), v.end(), v.begin(), 
//                                 ^^^^^^^^^
    std::back_inserter(r), [] (int a, int b) { return a + b; });

所以这里是完整的代码:

#include <algorithm>
#include <vector>

int main()
{
    std::vector<int> v {1, 2, 3, 4, 5, 6};
    std::vector<int> r;

    std::transform(v.begin(), v.end(), v.begin(),
        std::back_inserter(r), [] (int a, int b) { return a + b; });
}

这是一个编译的实时示例

但是,除非您只是想练习std::transform()在两个输入范围上操作的重载,否则您可以从评论中遵循Konrad Rudolph 的建议,并编写:

std::transform(v.begin(), v.end(), 
    std::back_inserter(r), [] (int a) { return a * 2; });

相反,如果您想对每对连续元素进行求和并将结果存储在r向量中,同时使用类似变换的方法,那么您可以求助于 Boost.Range,并编写如下内容:

#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>

// ...

namespace rng = boost::adaptors;

// This will fill r with values { 3, 7, 11 }
boost::transform(
    v | rng::strided(2),
    std::make_pair(v.begin() + 1, v.end()) | rng::strided(2),
    std::back_inserter(r),
    [] (int a, int b) { return a + b; });

这是一个活生生的例子

此外,正如 NeelBasu 在评论中指出的那样std::make_pair(),您可以基于sliced范围适配器编写一个更具表现力(和紧凑)的版本,而不是使用来定义第二个范围:

boost::transform(
    v | rng::strided(2),
    v | rng::sliced(1, v.size()) | rng::strided(2),
    std::back_inserter(r),
    [] (int a, int b) { return a + b; });
于 2013-06-08T15:30:55.697 回答