c++ - 使用 tcp::acceptor::async_accept 的套接字指针所有权转移

标签 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 处的示例中完成工作的方式据我所知)。

  • 你有更好的主意。

我在这里几乎不知所措。谁能赐教一下?

最佳答案

我试图找到一种使用 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,它按值而不是按右值引用保存对象,因为您的原始 unique_ptr 可能会离开范围(并被销毁),因为您正在使用异步 asio 调用。

关于c++ - 使用 tcp::acceptor::async_accept 的套接字指针所有权转移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3086782/

相关文章:

c++ - 非类型(引用)模板参数和链接

c++ - asio::strand 的拷贝是否会创建一个新的执行程序?

c++ - 诅咒库 : why does getch() clear my screen?

C# : catch all errors/exceptions of a mixed managed/unmanaged process

c++ - EnumDisplayDevices vs WMI Win32_DesktopMonitor,如何检测事件监视器?

C++:根据 struct 的整数之一对 vector <struct>(其中 struct 有 2 个整数)进行排序

c++ - 无法将 std::packaged_task 移动到 lambda 中

c++ - 从 tcp 迁移到 udp 时,‘acceptor’ 不是 ‘boost::asio::ip::udp’ 的成员

c++ - streambuf 与 boost::asio::async_write

c++ - ISO C++ 禁止声明没有类型的 "something"