1

I have a factory method returning a std::function

class Builder {
public:
    function<void(Data&)> build();
}

and a functor object

class Processor {
protected:
    vector<int> content_;
public:
    void operator()(Data&) { 
         ....
    }
}

Now I want to return the functor in the factory method, and I write

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

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

    return ret;
}

My question is: will ret maintain a copy of p? If so, when p.content_ is large, will that become a burden? What will be a suggested way to implement this?

Harper
  • 1,794
  • 14
  • 31

2 Answers2

4

A std::function hold and own its value. In fact, it requires callable object that are copiable so it can copy it when itself is copied.

Your function would be perfectly fine like this, and potentially faster:

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

    // fill items

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

However, if you copy the std::function around, the Processor object will be copied too, so the cost of copying the std::function depends on the type it contains (just as with any type erasure tools)

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
2

The constructor that will be used is this:

template< class F >
function( F f );

You can see that the object will be copied. If you want to avoid this, you can move the callable:

function<void(Data&)> ret(std::move(p));

The constructor will then move f to the internal storage.

If your callable is small, it will be stored directly in the function object. If it is too large, the internal storage will be allocated dynamically. Either way, moving resulting function object should be no more complex than moving the original callable object (when stored directly in the function) or probably even cheaper (when stored dynamically).

Copying should be avoided when performance is important, as it might involve dynamic allocations even if your callable doesn't need them.