【问题标题】:Can't move a smart ptr into a std::function无法将智能 ptr 移动到 std::function
【发布时间】:2020-01-31 19:41:11
【问题描述】:

我想创建一个std::function,将auto_ptr/unique_ptr 捕获到但无法正确执行。我需要一个适用于 c++11 的解决方案,但我什至不知道如何在 c++14 上做到这一点

以下示例适用于 c++11 (IncByTwenty) abd c++14 (IncByThirty)。但是,当我将那些 auto 更改为 Func 时,它不再编译。

typedef std::function<int( int )> Func;
Func IncByTen = std::bind( []( const int& p, int t ) -> int
{
    return p + t;  
}, 10, std::placeholders::_1 );

std::unique_ptr< int > pTwenty(new int(20));
// should have work in c++11 i think? cant assign to Func type
auto IncByTwenty = std::bind( []( const std::unique_ptr< int >& p, int t ) -> int
{
    return ( *p ) + t;  
}, std::move( pTwenty ), std::placeholders::_1 );

std::unique_ptr< int > pThirty = std::make_unique< int >( 30 );
// c++14  cant assign to Func type
auto IncByThirty  = [p{std::move(pThirty) }]( int t ) -> int
{
    return ( *p ) + t;  
};

std::cout << IncByTen(3) << " "  << IncByTwenty(4) << " " << IncByThirty(5);

我做错了吗?否则,我需要创建可分配给std::function 的东西,并且它需要使用移动运算符捕获一些局部变量。有什么建议吗?

【问题讨论】:

  • 不要在 C++11 中使用std::auto_ptr
  • 我想完全用 c++11 来做例子。实际上我使用的是内部uniqe_ptr 实现
  • std::auto_ptr 如何使示例完全使用 C++11? C++11 已被弃用。
  • 啊,我很笨。编辑帖子。我把它和 make_unique 混淆了
  • @taytay 不用担心,有时人们会感到困惑,因为 std::make_unique 只是添加到 C++14 中

标签: c++ c++11 c++14 smart-pointers


【解决方案1】:

无法将 [std::unique_ptr] 移动到 std::function

您不能,因为std::unique_ptr 不可复制。 (否则它不可能是唯一的)。 std::function 要求函数对象是可复制的。

有人提议为不可复制(特别是只能移动)函数对象添加函数包装器:P0228rX,但这样的提议还不是语言的一部分。

【讨论】:

    【解决方案2】:

    由于std::function是一个可复制类型的擦除容器,它只能包含可复制类型。

    std::function documentation 声明它需要这个(F 是发送给构造函数的类型):

    类型要求

    您的 lambda 必须可复制才能包含在 std::function

    您可以改用std::shared_ptr 或简单地使用非拥有指针:

    auto pThirty = std::make_unique<int>(30);
    
    auto IncByThirty = [p = pThirty.get()](int t) -> int {
        return *p + t;  
    };
    

    但是,您必须确保指向的数据与 lambda 以及包含它的所有 std::function 一样长。

    【讨论】:

    • 那是我所害怕的。在我的实际情况下,IncByThirty 的寿命会比pThirty 长,所以这行不通。我想将它移动到共享 ptr 唯一的方式。谢谢。
    • 在我的实际情况下,IncByThirtypThirty 寿命长。假设代码在函数中返回IncByThirty
    猜你喜欢
    • 2022-10-22
    • 2022-01-27
    • 1970-01-01
    • 2016-08-19
    • 2015-01-17
    • 1970-01-01
    • 2014-10-09
    • 1970-01-01
    相关资源
    最近更新 更多