从this问题我对仿函数(函数对象)有了很好的理解;如何初始化和调用它们。为了我自己的理解,我写了一些代码来解决这个问题
class Foo
{
private:
int x;
public:
Foo(int x) : x(x) {}
int operator()(int y) { return x + y; }
};
Foo poo(50);
int a = poo(50);
std::cout << a;
std::vector<int> vec(10);
std::vector<int> pec(10);
std::transform(vec.begin(), vec.end(), vec.begin(), poo(1));
并收到以下编译错误
Severity Code Description Project File Line Suppression State
Error C2064 term does not evaluate to a function taking 1 arguments
我在上面的问题中查看了一些评论并尝试了一个lambda表达式
std::transform(vec.begin(), vec.end(), vec.begin(), [](Foo poo) {return poo(1); });
有效,但我不明白为什么使用std::transform(in.begin(), in.end(), out.begin(), add_x(1));
的接受答案失败了。为什么我必须使用lambda表达式?另一个答案是做同样的事情,但它仍然会导致编译错误。那是为什么?
答案 0 :(得分:3)
这段代码很好用。
#include <iostream>
#include <array>
class add_x
{
private:
int x;
public:
add_x(int x) : x(x) {}
int operator()(int y) /* consider adding const here */
{ return x + y; }
};
int main()
{
std::array<int, 5> input { 1, 4, 9, 16, 25 };
std::array<int, 5> output;
std::transform(begin(input), end(input), begin(output), add_x(1));
for ( auto& val : output ) std::cout << val << "\n";
}
但是,调用const
成员函数可能是一个好主意,因为它不会改变仿函数。这也可能使它适用于更多版本的标准库。
这个和你的lambda版本之间的区别在于,在这里,常量1
被传递给构造函数以创建一个仿函数对象,并且数据被顺序传递给该单个仿函数实例的运算符。在lambda中,通过调用转换构造函数从每个数据创建一个新对象,然后将常量传递给运算符。也就是说,您的变通方法会交换x
和y
,并且还会更改实例数。
答案 1 :(得分:1)
如果添加定义,它也有效:
[{
slug: "brand",
...,
domain: {
production: 'www.domain.com'
}
}, {
slug: "brand1",
...,
domain: {
production: 'www.domain1.com'
}]
只需将poo发送到transform,而不进行(1)调用。变换需要一个带有()运算符的对象来调用,并单独声明它使它的范围更加清晰。