I'm working on Asynchronous networking code for use in a library, and my code designed to 'send' data works pretty flawlessly:
//connection_id is a wrapper around a size_t
//data_vector is an alias for std::vector<unsigned char>
bool write_to_connection(const connection_id & id, const data_vector & data) {
if (connections.contains(id)) {
std::shared_ptr<data_vector> write_buffer = std::make_shared<data_vector>(data);
connection_ptr conn = connections[id];
conn->get_socket().async_write_some(
boost::asio::buffer(
*write_buffer
),
std::bind(
&basic_server::write,
this,
std::placeholders::_1,
std::placeholders::_2,
id,
write_buffer
)
);
return true;
}
return false;
}
void write(const boost::system::error_code & ec, size_t bytes_written, const connection_id & id, std::shared_ptr<data_vector> write_buffer) {
if (ec) {
connections.erase(id);
}
}
However, for performance reasons, I don't like the use of std::shared_ptr
to maintain my data, especially since I might be issuing many, many of these callbacks at once. I don't even use it in the callback function, and only add it to ensure that the data buffer's lifetime lasts until the write completes.
I'd like to use std::unique_ptr
, since I only logically need one copy of the object at any given time, which gets passed along (read: moved) to the callback function, which I've written like this:
//connection_id is a wrapper around a size_t
//data_vector is an alias for std::vector<unsigned char>
bool write_to_connection(const connection_id & id, const data_vector & data) {
if (connections.contains(id)) {
std::unique_ptr<data_vector> write_buffer = std::make_unique<data_vector>(data);
connection_ptr conn = connections[id];
conn->get_socket().async_write_some(
boost::asio::buffer(
*write_buffer
),
std::bind(
&basic_server::write,
this,
std::placeholders::_1,
std::placeholders::_2,
id,
std::move(write_buffer) //So that we're not performing a copy; we're performing a move
)
);
return true;
}
return false;
}
void write(const boost::system::error_code & ec, size_t bytes_written, const connection_id & id, std::unique_ptr<data_vector> write_buffer) {
if (ec) {
connections.erase(id);
}
}
However, this promptly gives me this (quite verbose) compile error:
Error C2280 'std::_Binder<std::_Unforced,void (__cdecl server::basic_server::* )(const boost::system::error_code &,size_t,const server::connection_id &,std::unique_ptr<server::data_vector,std::default_delete<_Ty>>),server::basic_server *const ,const std::_Ph<1> &,const std::_Ph<2> &,const server::connection_id &,std::unique_ptr<_Ty,std::default_delete<_Ty>>>::_Binder(const std::_Binder<std::_Unforced,void (__cdecl server::basic_server::* )(const boost::system::error_code &,size_t,const server::connection_id &,std::unique_ptr<_Ty,std::default_delete<_Ty>>),server::basic_server *const ,const std::_Ph<1> &,const std::_Ph<2> &,const server::connection_id &,std::unique_ptr<_Ty,std::default_delete<_Ty>>> &)': attempting to reference a deleted function Send File To Server C:\Users\rengland\Workspace_CPP\Library\Includes\boost\asio\basic_stream_socket.hpp 729
I'm assuming that it's complaining because the code thinks I'm trying to copy the std::unique_ptr
, despite my intent being to move it into the callback function. Is there anything I can do to fix this issue, or should I just resign myself to using the std::shared_ptr
version?