简体   繁体   English

带有unique_ptr参数的std :: function

[英]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 不可能(MSVC 2012)创建像这样的仿函数

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. 问题不在于绑定 - 使用auto f = std::bind(...)有效。 Also, using a shared_ptr also works 此外,使用shared_ptr也有效

  • Why is unique_ptr disallowed? 为什么不允许unique_ptr?
  • Is this a MSVC problem or general C++11 restriction? 这是MSVC问题还是一般的C ++ 11限制?
  • Is there a work-around without changing the function definition? 有没有改变功能定义的解决方法?

The code below compiles fine using gcc 4.8. 下面的代码使用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. 您会注意到,如果未使用move调用“g”(将左值转换为右值),则代码无法编译。 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. 如前所述,绑定成功,因为只有在调用operator()(...)时才会发生失败,因为unique_ptr不可复制。 The call "f" is permissible, as shared_ptr has a copy constructor. 调用“f”是允许的,因为shared_ptr有一个复制构造函数。

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

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. 但如果您无法更改功能定义,则无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM