4

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

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

我注意到我不能将 std::bind() 和 std::unique_ptr<> 作为参数,因为 std::bind() 要求它的参数是 CopyConstructible 的,这是理所当然的。不仅如此,Boost 的 AcceptHandler 概念也要求是 CopyConstructible。

所以我的选择是:

或者

  • 你对我有更好的主意。

我在这里几乎不知所措。任何人都可以启发我吗?

4

1 回答 1

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

于 2011-03-03T19:48:29.843 回答