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

时间:2015-03-14 18:14:15

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

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

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

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

在类定义中使用类成员变量:

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上的文档,我看到有一些我不太了解的新指针概念,应该阅读,但在那之前,我更喜欢工作{{1}对象。

::work是否保护我不会做一些会使其保证失效的事情?我不应该在这里使用unique_ptr吗?或者我没有正确的语法?我应该使用unique_ptr吗?

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

使用unique_ptr::reset

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

将unique_ptr用于延迟构造是有效的,尽管使用std / boost optional会更理想,除非您还明确需要/想要动态分配它。我还要注意,您应该尝试设计类,以便可以在构造函数中完全构造所有内容,而不需要延迟构造。但有时它是不可避免的。