使用tcp :: acceptor :: async_accept传递所有权的套接字指针

时间:2010-06-21 17:09:34

标签: c++ c++11 boost-asio unique-ptr

我最近开始在一个项目中使用Boost.Asio,并且想知道是否有人知道将新创建的套接字的所有权转移到tcp :: acceptor :: async_accept的干净解决方案,这将转而转移此所有权到接受处理函数。

这不是一种不连贯的愿望,请注意,因为处理程序只需要调用一次。

我注意到我不能std :: bind()std :: unique_ptr<>作为参数,因为std :: bind()要求其参数为CopyConstructible,这是正确的。不仅如此,Boost的AcceptHandler概念也必须是CopyConstructible。

所以我的选择是:

  • 去弃用的std :: auto_ptr<>使用复制构造函数移动对象的方法,可能会在Boost.Asio的新版本上造成模糊的错误。
  • 使用std :: shared_ptr<>一旦不再需要,就无法将共享所有权从指针中取出,即当它到达实际的处理函数时(就我所读到的http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/examples.html上的示例而言,这是完成的工作方式)。

  • 你对我有更好的想法。

我在这里几乎不知所措。谁能开导我?

1 个答案:

答案 0 :(得分:1)

我尝试使用c ++ 0x标准库找到一种方法,但不能。 最后我决定编写自己的rvalue_reference_wrapper和rvalue_ref()便利类。与std :: bind一样,你需要将非可复制对象包装在可复制的东西中(reference_wrapper是最好的例子)。您也可以刚刚传递指针,但这意味着更改您的界面。

这适用于我的机器:

#include <iostream>
#include <functional>
#include <memory>

template< class T >
struct rvalue_reference_wrapper
{
    rvalue_reference_wrapper( T&& t )
        : t_(std::move(t))
    {}

    operator T&&() const volatile
    {
        return std::move(t_);
    }

private:
    T&& t_; 
};

template< class T >
rvalue_reference_wrapper<T> rvalue_ref( T&& t )
{
    return rvalue_reference_wrapper<T>(std::move(t));
}

void go( std::unique_ptr<int> i )
{
    std::cout << *i << std::endl;
}

int main()
{
    std::unique_ptr<int> i(new int(1));

    auto b = std::bind( go, rvalue_ref(std::move(i)) );
    //auto b = std::bind( go, std::ref(std::move(i)) ); // Wont work

    b();
}

我没有使代码具有防弹功能,但欢迎讨论rvalue_reference_wrapper的需要,或者如何使用std :: reference_wrapper来模拟代码。

另外,对于您的特定情况,您可能需要编写rvalue_reference_wrapper的差异版本,它通过值而非rvalue引用保存对象,因为您原来的unique_ptr可能会离开范围(并被销毁),因为您正在使用异步asio调用。