不能在构造函数中使用 boost.asio 解析器
Can't use boost.asio resolver in constructor
我有一个 class,其属性是这样定义的:
private:
const std::string m_ip;
bool is_connected;
boost::asio::io_service m_io_service;
tcp::resolver m_resolver;
tcp::resolver::query m_query;
tcp::resolver::iterator m_endpoint_iterator;
tcp::socket m_socket;
以及我这样定义的构造函数实现:
Connection::Connection(const std::string ip)
: m_ip(ip)
, is_connected(false)
, m_resolver(tcp::resolver(&m_io_service))
, m_query(tcp::resolver::query(m_ip, "connect_back"))
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(tcp::socket(m_io_service))
{}
在这里,在构造函数中,我定义了几乎所有需要定义的属性。
但是我遇到了一个完整的 .cpp
文件中从未遇到过的问题:当我在构造函数中定义解析器时,编译器说我遇到了一个错误:
/home/User/C++ Projects/Client/Network.cpp:9: error: no matching function for call to ‘boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::basic_resolver(boost::asio::io_service*)’
Connection::Connection(const std::string ip) : m_ip(ip), is_connected(false), m_resolver(tcp::resolver(&m_io_service)), m_query(tcp::resolver::query(m_ip, "connect_back")), m_endpoint_iterator(m_resolver.resolve(m_query)), m_socket(tcp::socket(m_io_service)){
^
我不明白为什么,因为我用的是正规的东西!
有什么想法吗?
PS :
如果我尝试从 m_io_service
中删除 &
,我会得到更多错误:
/home/User/C++ Projects/Client/Network.cpp:9: error: use of deleted function ‘boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::basic_resolver(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>&&)’
Connection::Connection(const std::string ip) : m_ip(ip),
is_connected(false),
m_resolver(tcp::resolver(m_io_service)),
m_query(tcp::resolver::query(m_ip, "connect_back")),
m_endpoint_iterator(m_resolver.resolve(m_query)),
m_socket(tcp::socket(m_io_service)){
和
/usr/include/boost/asio/ip/basic_resolver.hpp:44: error: ‘boost::asio::basic_io_object<IoObjectService, Movable>::basic_io_object(const boost::asio::basic_io_object<IoObjectService, Movable>&) [with IoObjectService = boost::asio::ip::resolver_service<boost::asio::ip::tcp>; bool Movable = false]’ is private within this context
constructor for boost::asio::ip::basic_resolver
通过引用接受参数:
basic_resolver(boost::asio::io_service& io_service)
并且您已经获取了变量的地址并传递了一个指针:
m_resolver(tcp::resolver(&m_io_service))
尝试删除 &
。
添加到@Muscampester 的回答中,看起来你的构造函数是多余的。
Connection::Connection(const std::string ip)
: m_ip(ip)
, is_connected(false)
, m_resolver(tcp::resolver(&m_io_service))
, m_query(tcp::resolver::query(m_ip, "connect_back"))
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(tcp::socket(m_io_service))
{}
应该这样写:
//I changed this to const& because, while Copy Ellision *might* optimize this, it's still
//more semantically correct to pass by const reference.
Connection::Connection(const std::string & ip)
: m_ip(ip)
, is_connected(false)
//Note that we're no longer referring to the underlying type.
, m_resolver(m_io_service)
, m_query(m_ip, "connect_back")
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(m_io_service)
{}
不同之处在于您的解析器、查询和套接字对象不再是 "move-constructed",而是直接构造的。根据您遇到的第二个错误,看起来您使用的是 boost 版本,其中这些对象不是 movable/move-constructable(或者可能 boost 从未打算让这些类型可移动;不确定是哪个)。
如果您使用的是旧版本的 boost,请尝试更新到更高版本的库。但是,无论您是否这样做,您都需要更新代码,这样您就不再是不必要的 move-constructing.
我有一个 class,其属性是这样定义的:
private:
const std::string m_ip;
bool is_connected;
boost::asio::io_service m_io_service;
tcp::resolver m_resolver;
tcp::resolver::query m_query;
tcp::resolver::iterator m_endpoint_iterator;
tcp::socket m_socket;
以及我这样定义的构造函数实现:
Connection::Connection(const std::string ip)
: m_ip(ip)
, is_connected(false)
, m_resolver(tcp::resolver(&m_io_service))
, m_query(tcp::resolver::query(m_ip, "connect_back"))
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(tcp::socket(m_io_service))
{}
在这里,在构造函数中,我定义了几乎所有需要定义的属性。
但是我遇到了一个完整的 .cpp
文件中从未遇到过的问题:当我在构造函数中定义解析器时,编译器说我遇到了一个错误:
/home/User/C++ Projects/Client/Network.cpp:9: error: no matching function for call to ‘boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::basic_resolver(boost::asio::io_service*)’
Connection::Connection(const std::string ip) : m_ip(ip), is_connected(false), m_resolver(tcp::resolver(&m_io_service)), m_query(tcp::resolver::query(m_ip, "connect_back")), m_endpoint_iterator(m_resolver.resolve(m_query)), m_socket(tcp::socket(m_io_service)){
^
我不明白为什么,因为我用的是正规的东西!
有什么想法吗?
PS :
如果我尝试从 m_io_service
中删除 &
,我会得到更多错误:
/home/User/C++ Projects/Client/Network.cpp:9: error: use of deleted function ‘boost::asio::ip::basic_resolver<boost::asio::ip::tcp>::basic_resolver(boost::asio::ip::basic_resolver<boost::asio::ip::tcp>&&)’
Connection::Connection(const std::string ip) : m_ip(ip),
is_connected(false),
m_resolver(tcp::resolver(m_io_service)),
m_query(tcp::resolver::query(m_ip, "connect_back")),
m_endpoint_iterator(m_resolver.resolve(m_query)),
m_socket(tcp::socket(m_io_service)){
和
/usr/include/boost/asio/ip/basic_resolver.hpp:44: error: ‘boost::asio::basic_io_object<IoObjectService, Movable>::basic_io_object(const boost::asio::basic_io_object<IoObjectService, Movable>&) [with IoObjectService = boost::asio::ip::resolver_service<boost::asio::ip::tcp>; bool Movable = false]’ is private within this context
constructor for boost::asio::ip::basic_resolver
通过引用接受参数:
basic_resolver(boost::asio::io_service& io_service)
并且您已经获取了变量的地址并传递了一个指针:
m_resolver(tcp::resolver(&m_io_service))
尝试删除 &
。
添加到@Muscampester 的回答中,看起来你的构造函数是多余的。
Connection::Connection(const std::string ip)
: m_ip(ip)
, is_connected(false)
, m_resolver(tcp::resolver(&m_io_service))
, m_query(tcp::resolver::query(m_ip, "connect_back"))
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(tcp::socket(m_io_service))
{}
应该这样写:
//I changed this to const& because, while Copy Ellision *might* optimize this, it's still
//more semantically correct to pass by const reference.
Connection::Connection(const std::string & ip)
: m_ip(ip)
, is_connected(false)
//Note that we're no longer referring to the underlying type.
, m_resolver(m_io_service)
, m_query(m_ip, "connect_back")
, m_endpoint_iterator(m_resolver.resolve(m_query))
, m_socket(m_io_service)
{}
不同之处在于您的解析器、查询和套接字对象不再是 "move-constructed",而是直接构造的。根据您遇到的第二个错误,看起来您使用的是 boost 版本,其中这些对象不是 movable/move-constructable(或者可能 boost 从未打算让这些类型可移动;不确定是哪个)。
如果您使用的是旧版本的 boost,请尝试更新到更高版本的库。但是,无论您是否这样做,您都需要更新代码,这样您就不再是不必要的 move-constructing.