Reputation: 9369
Both GCC 4.7.3 and 4.8.0 on Coliru fail to compile the following code. It looks like asio
timers are not movable:
#include <vector>
#include <chrono>
#include <boost/asio.hpp>
#include <boost/asio/system_timer.hpp>
int main() {
boost::asio::io_service io;
boost::asio::system_timer t{io}; // works
std::vector<boost::asio::system_timer> timers;
timers.emplace_back(io); // timer cannot be constrcuted in place
timers.push_back(std::move(t)); // cannot be moved as well
}
Do you know why and way to create a vector of timers? In my case, one solution would be to use a vector of unique pointers, but I prefer to avoid that.
The error from the compiler is:
In file included from /usr/include/c++/4.8/vector:62:0,
from main.cpp:1:
/usr/include/c++/4.8/bits/stl_construct.h: In instantiation of 'void
std::_Construct(_T1*, _Args&& ...) [with _T1 =
boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>
_Args = {boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock,
boost::asio::wait_traits<std::chrono::_V2::system_clock>,
boost::asio::waitable_timer_service<std::chrono::_V2::system_clock,
boost::asio::wait_traits<std::chrono::_V2::system_clock> > >}]':
/usr/include/c++/4.8/bits/stl_uninitialized.h:75:53: required from
'static _ForwardIterator
std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*>
_ForwardIterator = boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*;
bool _TrivialValueTypes = false]'
/usr/include/c++/4.8/bits/stl_uninitialized.h:117:41: required from
'_ForwardIterator std::uninitialized_copy(_InputIterator,
_InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*>
_ForwardIterator = boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*]'
/usr/include/c++/4.8/bits/stl_uninitialized.h:258:63: required from
'_ForwardIterator std::__uninitialized_copy_a(_InputIterator,
_InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*>
_ForwardIterator = boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*;
_Tp = boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>]'
/usr/include/c++/4.8/bits/stl_uninitialized.h:281:69: required from
'_ForwardIterator
std::__uninitialized_move_if_noexcept_a(_InputIterator,
_InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*;
_ForwardIterator = boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>*;
_Allocator = std::allocator<boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>
>]'
/usr/include/c++/4.8/bits/vector.tcc:415:43: required from 'void
std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args
= {boost::asio::io_service&}; _Tp = boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>
_Alloc = std::allocator<boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>
>]'
/usr/include/c++/4.8/bits/vector.tcc:101:54: required from 'void
std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args =
{boost::asio::io_service&}; _Tp =
boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>
_Alloc = std::allocator<boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>
>]'
main.cpp:10:27: required from here
/usr/include/c++/4.8/bits/stl_construct.h:75:7: error: use of deleted
function
'boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>::basic_waitable_timer(boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>&&)'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
In file included from /usr/local/include/boost/asio.hpp:33:0,
from main.cpp:3:
/usr/local/include/boost/asio/basic_waitable_timer.hpp:127:7: note:
'boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>::basic_waitable_timer(boost::asio::basic_waitable_timer<std::chrono::_V2::system_clock>&&)'
is implicitly deleted because the default definition would be
ill-formed:
class basic_waitable_timer
^
In file included from
/usr/local/include/boost/asio/basic_socket.hpp:20:0,
from /usr/local/include/boost/asio/basic_datagram_socket.hpp:20,
from /usr/local/include/boost/asio.hpp:21,
from main.cpp:3:
/usr/local/include/boost/asio/basic_io_object.hpp:163:3: error:
'boost::asio::basic_io_object<IoObjectService,
Movable>::basic_io_object(const
boost::asio::basic_io_object<IoObjectService, Movable>&) [with
IoObjectService =
boost::asio::waitable_timer_service<std::chrono::_V2::system_clock,
boost::asio::wait_traits<std::chrono::_V2::system_clock> > bool
Movable = false]' is private
basic_io_object(const basic_io_object&);
^
In file included from /usr/local/include/boost/asio.hpp:33:0,
from main.cpp:3:
/usr/local/include/boost/asio/basic_waitable_timer.hpp:127:7: error:
within this context
class basic_waitable_timer
^
Upvotes: 2
Views: 1155
Reputation: 72072
ASIO hasn't been updated with move semantics yet (or at least parts of it), so the timer isn't movable. So your choices are
unique_ptr
.deque
or list
.That would look like this:
#include <deque>
#include <chrono>
#include <boost/asio.hpp>
#include <boost/asio/system_timer.hpp>
int main() {
boost::asio::io_service io;
boost::asio::system_timer t{io}; // works
std::deque<boost::asio::system_timer> timers;
timers.emplace_back(io); // should work
timers.push_back(std::move(t)); // won't work
}
But don't try to use insert
or erase
for the collection, because those require movability.
Upvotes: 4