C++将函子对象返回为STD::函数

C++将函子对象返回为STD::函数,c++,functor,std-function,C++,Functor,Std Function,我有一个返回std::函数的工厂方法 和一个函子对象 class Processor { protected: vector<int> content_; public: void operator()(Data&) { .... } } 现在我想返回工厂方法中的函子,然后我写 function<void(Data&)> build() { Processor p; // Add items t

我有一个返回std::函数的工厂方法

和一个函子对象

class Processor {
protected:
    vector<int> content_;
public:
    void operator()(Data&) { 
         ....
    }
}
现在我想返回工厂方法中的函子,然后我写

function<void(Data&)> build() {
    Processor p;
    // Add items to p.content_

    function<void(Data&)> ret(p);

    return ret;
}
我的问题是:ret会保留一份p吗?如果是这样,当p.含量很大时,这会成为负担吗?实现这一点的建议方法是什么?

std::函数保持并拥有其值。事实上,它需要可复制的可调用对象,以便在复制自身时可以复制它

您的函数将非常好,并且可能更快:

function<void(Data&)> build() {
    Processor p;

    // fill items

    return p; // p moved into the returned std::function (since C++14)
}
但是,如果复制std::function,处理器对象也会被复制,因此复制std::function的成本取决于它包含的类型,就像任何类型擦除工具一样。事实上,它需要可复制的可调用对象,以便在复制自身时可以复制它

您的函数将非常好,并且可能更快:

function<void(Data&)> build() {
    Processor p;

    // fill items

    return p; // p moved into the returned std::function (since C++14)
}

但是,如果复制std::function,处理器对象也会被复制,因此复制std::function的成本取决于它包含的类型,就像任何类型擦除工具一样,将使用的构造函数是:

您可以看到对象将被复制。如果要避免这种情况,可以移动可调用项:

function<void(Data&)> ret(std::move(p));
然后构造函数将f移动到内部存储器

如果您的可调用项很小,它将直接存储在函数对象中。如果太大,内部存储将动态分配。无论哪种方式,移动结果函数对象都不应该比直接存储在函数中时移动原始可调用对象更复杂,或者动态存储时更便宜


当性能很重要时,应避免复制,因为它可能涉及动态分配,即使您的可调用对象不需要动态分配。

将使用的构造函数是:

您可以看到对象将被复制。如果要避免这种情况,可以移动可调用项:

function<void(Data&)> ret(std::move(p));
然后构造函数将f移动到内部存储器

如果您的可调用项很小,它将直接存储在函数对象中。如果太大,内部存储将动态分配。无论哪种方式,移动结果函数对象都不应该比直接存储在函数中时移动原始可调用对象更复杂,或者动态存储时更便宜


当性能很重要时,应避免复制,因为即使您的可调用对象不需要动态分配,复制也可能涉及动态分配。

使用void operator data&&和函数retstd::movep;。您需要实现move构造函数,还需要记住Processor类的第5条规则。。难道综合动作还不够吗?零规则!您确实需要返回std::moveretthough@AsteroidsWithWings在返回时从本地移动。假设您不介意复制处理器,则您的代码与编写的代码一样正常。事实上,ret复制了p。您可以使用函数retstd::movep@AsteroidsWithWings我确信返回值优化会考虑std::moveret。使用void操作符data&&和函数retstd::movep;。您需要实现move构造函数,还需要记住Processor类的第5条规则。。难道综合动作还不够吗?零规则!您确实需要返回std::moveretthough@AsteroidsWithWings在返回时从本地移动。假设您不介意复制处理器,则您的代码与编写的代码一样正常。事实上,ret复制了p。您可以使用函数retstd::movep@AsteroidsWithWings我很确定返回值优化会考虑std::moveret。感谢您的回答。我还需要对局部变量进行更改,例如,将项目添加到其内容中,因此我需要局部变量存在。@Harper我刚刚添加了最后一段。希望它能帮助谢谢你的回答。我还需要对局部变量进行更改,例如,将项目添加到其内容中,因此我需要局部变量存在。@Harper我刚刚添加了最后一段。希望能有帮助