将 unique_ptr 分配给新的 boost::asio::io_service::work 对象的正确语法?

Correct syntax to assign unique_ptr to new boost::asio::io_service::work object?

std::unique_ptr<boost::asio::io_service::work> 指针分配给新的 boost::asio::io_service::work 对象的正确语法是什么?

我正在将 boost::asio 代码从使用静态函数和全局变量转换为 class 实现,但这意味着我必须替换工作初始化:

std::unique_ptr<boost::asio::io_service::work> KeepAlive(
  new boost::asio::io_service::work(TheASIOService));

with a class member variable in a class definition:

std::unique_ptr<boost::asio::io_service::work> KeepAlive;

稍后分配给新值:

KeepAlive = new boost::asio::io_service::work(IO_Service);

编译器根据参数类型拒绝哪个(Boost 错误的括号):

g++ -std=c++0x -c -Wall ../comms/CommServer.cpp
../comms/CommServer.cpp: In member function ‘void CommServer::Listen()’:
../comms/CommServer.cpp:39:13: error: no match for ‘operator=’ (operand types are ‘std::unique_ptr<boost::asio::io_service::work>’ and ‘boost::asio::io_service::work*’)
   KeepAlive = new boost::asio::io_service::work(IO_Service);
             ^
../comms/CommServer.cpp:39:13: note: candidates are:
In file included from /usr/include/c++/4.8/memory:81:0,
                 from /usr/include/boost/config/no_tr1/memory.hpp:21,
                 from /usr/include/boost/get_pointer.hpp:14,
                 from /usr/include/boost/bind/mem_fn.hpp:25,
                 from /usr/include/boost/mem_fn.hpp:22,
                 from /usr/include/boost/bind/bind.hpp:26,
                 from /usr/include/boost/bind.hpp:22,
                 from ../comms/Comms.h:16,
                 from ../comms/CommServer.h:16,
                 from ../comms/CommServer.cpp:10:
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = boost::asio::io_service::work; _Dp = std::default_delete<boost::asio::io_service::work>]
       operator=(unique_ptr&& __u) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note:   no known conversion for argument 1 from ‘boost::asio::io_service::work*’ to ‘std::unique_ptr<boost::asio::io_service::work>&&’
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note: template<class _Up, class _Ep> typename std::enable_if<std::__and_<std::is_convertible<typename std::unique_ptr<_Up, _Ep>::pointer, typename std::unique_ptr<_Tp, _Dp>::_Pointer::type>, std::__not_<std::is_array<_Up> > >::value, std::unique_ptr<_Tp, _Dp>&>::type std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Up, _Ep>&&) [with _Up = _Up; _Ep = _Ep; _Tp = boost::asio::io_service::work; _Dp = std::default_delete<boost::asio::io_service::work>]
  operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
  ^
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note:   template argument deduction/substitution failed:
../comms/CommServer.cpp:39:13: note:   mismatched types ‘std::unique_ptr<_Tp, _Dp>’ and ‘boost::asio::io_service::work*’
   KeepAlive = new boost::asio::io_service::work(IO_Service);
             ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from /usr/include/boost/config/no_tr1/memory.hpp:21,
                 from /usr/include/boost/get_pointer.hpp:14,
                 from /usr/include/boost/bind/mem_fn.hpp:25,
                 from /usr/include/boost/mem_fn.hpp:22,
                 from /usr/include/boost/bind/bind.hpp:26,
                 from /usr/include/boost/bind.hpp:22,
                 from ../comms/Comms.h:16,
                 from ../comms/CommServer.h:16,
                 from ../comms/CommServer.cpp:10:
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::nullptr_t) [with _Tp = boost::asio::io_service::work; _Dp = std::default_delete<boost::asio::io_service::work>; std::nullptr_t = std::nullptr_t]
       operator=(nullptr_t) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note:   no known conversion for argument 1 from ‘boost::asio::io_service::work*’ to ‘std::nullptr_t’

我检查了 documentation for the unique_ptr's assignment operator 并发现该示例出于某种原因在对 std::move() 的调用中包装了一个分配的值,但编译器以类似的方式对此犹豫不决:

g++ -std=c++0x -c -Wall ../comms/CommServer.cpp
../comms/CommServer.cpp: In member function ‘void CommServer::Listen()’:
../comms/CommServer.cpp:39:13: error: no match for ‘operator=’ (operand types are ‘std::unique_ptr<boost::asio::io_service::work>’ and ‘std::remove_reference<boost::asio::io_service::work*>::type {aka boost::asio::io_service::work*}’)
   KeepAlive = std::move(new boost::asio::io_service::work(IO_Service));
             ^
../comms/CommServer.cpp:39:13: note: candidates are:
In file included from /usr/include/c++/4.8/memory:81:0,
                 from /usr/include/boost/config/no_tr1/memory.hpp:21,
                 from /usr/include/boost/get_pointer.hpp:14,
                 from /usr/include/boost/bind/mem_fn.hpp:25,
                 from /usr/include/boost/mem_fn.hpp:22,
                 from /usr/include/boost/bind/bind.hpp:26,
                 from /usr/include/boost/bind.hpp:22,
                 from ../comms/Comms.h:16,
                 from ../comms/CommServer.h:16,
                 from ../comms/CommServer.cpp:10:
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = boost::asio::io_service::work; _Dp = std::default_delete<boost::asio::io_service::work>]
       operator=(unique_ptr&& __u) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:190:7: note:   no known conversion for argument 1 from ‘std::remove_reference<boost::asio::io_service::work*>::type {aka boost::asio::io_service::work*}’ to ‘std::unique_ptr<boost::asio::io_service::work>&&’
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note: template<class _Up, class _Ep> typename std::enable_if<std::__and_<std::is_convertible<typename std::unique_ptr<_Up, _Ep>::pointer, typename std::unique_ptr<_Tp, _Dp>::_Pointer::type>, std::__not_<std::is_array<_Up> > >::value, std::unique_ptr<_Tp, _Dp>&>::type std::unique_ptr<_Tp, _Dp>::operator=(std::unique_ptr<_Up, _Ep>&&) [with _Up = _Up; _Ep = _Ep; _Tp = boost::asio::io_service::work; _Dp = std::default_delete<boost::asio::io_service::work>]
  operator=(unique_ptr<_Up, _Ep>&& __u) noexcept
  ^
/usr/include/c++/4.8/bits/unique_ptr.h:203:2: note:   template argument deduction/substitution failed:
../comms/CommServer.cpp:39:13: note:   mismatched types ‘std::unique_ptr<_Tp, _Dp>’ and ‘std::remove_reference<boost::asio::io_service::work*>::type {aka boost::asio::io_service::work*}’
   KeepAlive = std::move(new boost::asio::io_service::work(IO_Service));
             ^
In file included from /usr/include/c++/4.8/memory:81:0,
                 from /usr/include/boost/config/no_tr1/memory.hpp:21,
                 from /usr/include/boost/get_pointer.hpp:14,
                 from /usr/include/boost/bind/mem_fn.hpp:25,
                 from /usr/include/boost/mem_fn.hpp:22,
                 from /usr/include/boost/bind/bind.hpp:26,
                 from /usr/include/boost/bind.hpp:22,
                 from ../comms/Comms.h:16,
                 from ../comms/CommServer.h:16,
                 from ../comms/CommServer.cpp:10:
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note: std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(std::nullptr_t) [with _Tp = boost::asio::io_service::work; _Dp = std::default_delete<boost::asio::io_service::work>; std::nullptr_t = std::nullptr_t]
       operator=(nullptr_t) noexcept
       ^
/usr/include/c++/4.8/bits/unique_ptr.h:211:7: note:   no known conversion for argument 1 from ‘std::remove_reference<boost::asio::io_service::work*>::type {aka boost::asio::io_service::work*}’ to ‘std::nullptr_t’

阅读 std::move 上的文档,我发现有一些我不太理解的新指针概念,应该继续阅读,但在那之前,我宁愿使用一个有效的 ::work对象。

unique_ptr 是在保护我免于做出使其保证无效的事情吗?我不应该在这里使用 unique_ptr 吗?或者我只是没有正确的语法?我应该使用 unique_ptr::reset(new ...) 吗?

使用unique_ptr::reset:

keepAlive.reset(new boost::asio::io_service::work(IO_Service));

延迟构造使用unique_ptr是有效的,尽管使用std/boostoptional会更理想,除非你也显式need/want动态分配它.我还会指出,您应该尝试设计 类 以便您可以在构造函数中完全构造所有内容,而不需要延迟构造。但有时又是不可避免的。

查看 std::unique_ptr<> 的文档。你会发现 unique_ptr<>::reset() 是你的朋友:

KeepAlive.reset(new boost::asio::io_service::work(IO_Service));