Search code examples
c++c++11unique-ptrstd-functionstdbind

std::function with unique_ptr argument


Given a function like

void MyFunction(std::unique_ptr<int> arg);

it is not possible (MSVC 2012) to create a functor like

std::function<void(std::unique_ptr<int>)> f = std::bind(&MyFunction, std::placeholders::_1);

The problem is not the bind - using auto f = std::bind(...) works. Also, using a shared_ptr also works

  • Why is unique_ptr disallowed?
  • Is this a MSVC problem or general C++11 restriction?
  • Is there a work-around without changing the function definition?

Solution

  • The code below compiles fine using gcc 4.8. You will notice that if "g" is not called with move (that converts the lvalue to an rvalue), the code fails to compile. As mentioned earlier, the bind succeeds because the failure only happens when operator()( ... ) is called, because of the fact that unique_ptr is not copyable. The call "f" is permissible, as shared_ptr has a copy constructor.

    #include <functional>
    #include <memory>
    
    
    void foo1( std::shared_ptr<int> ){}
    void foo2( std::unique_ptr<int> ){}
    
    int main() 
    {
        using namespace std::placeholders;
    
        std::function<void(std::shared_ptr<int>)> f = std::bind( foo1, _1 );
        std::function<void(std::unique_ptr<int>)> g = std::bind( foo2, _1 );
    
        std::unique_ptr<int> i( new int(5) );
        g( move( i ) ); //Requires the move
    
        std::shared_ptr<int> j( new int(5) );
        f( j ); //Works fine without the move
        return 0;
    }