使用for_each或std::transform时,c++函函数构造函数是如何被调用的?

How do C++ functor constructors get called when used with for_each or std::transform

本文关键字:构造函数 函数 调用 c++ each for std transform 使用      更新时间:2023-10-16

我以前从未使用过c++函子,所以我只是想了解它们是如何工作的。

。假设我们有这个函子类

class MultiplyBy {
private:
    int factor;
public:
    MultiplyBy(int x) : factor(x) { }
    int operator () (int other) const {
        return factor * other;
    }
};

像这样使用对我来说很清楚:

MultiplyBy mult_3(3);
int x = mult_3(100);

显然,使用参数3调用了MultiplyBy的构造函数。

但是在下面的例子中,如何使用数组中的值调用构造函数?

int array[5] = {1, 2, 3, 4, 5};
std::transform(array, array + 5, array, MultiplyBy(3));

那么,在最后一种情况下,您将创建一个新的MultiplyBy对象,其中3作为构造函数参数。这个对象然后被传递给std::transform,然后它调用operator()

如果它能帮助你更好地理解,这是相同的:

int array[] = {1, 2, 3, 4, 5};
MultiplyBy times3(3);
std::transform(array, array + 5, array, times3);

你可以把转换想象成这样的结构:

void transform(Iterator b, Iterator e, Functor f)
{
    for(;b != e; ++b)
    {
        *b = f(*b);
    }
}

函子按值传递给函数。
所以当你像这样调用:

std::transform(array, array + 5, array, MultiplyBy(3));

在这里您已经创建了一个临时对象。它作为参数值传递给transfer()。这将导致函数被复制到函数中(这不是问题,因为它只有一个POD成员,并且编译器生成的复制构造函数工作得很好)。然后该参数就可以正常使用了。

注意:临时对象在创建它的表达式的末尾被销毁(将在transform()返回之后)。

MultiplyBy(3)创建一个未命名的临时变量,该变量传递给transform,并且(在此时)给出该函数中参数的相应名称。