Question

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?
Was it helpful?

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;
}

OTHER TIPS

A workaround is to have

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

but that doesn't work if you can't change the function definition.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top