【问题标题】:Can't use boost.asio resolver in constructor不能在构造函数中使用 boost.asio 解析器
【发布时间】:2017-01-16 20:09:14
【问题描述】:

我有一个类,我定义的属性如下:

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 中删除&amp;,我会得到更多错误:

/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&lt;IoObjectService, Movable&gt;::basic_io_object(const boost::asio::basic_io_object&lt;IoObjectService, Movable&gt;&amp;) [with IoObjectService = boost::asio::ip::resolver_service&lt;boost::asio::ip::tcp&gt;; bool Movable = false]’ is private within this context

【问题讨论】:

  • 真的不希望每个连接都有一个 io_service。它们都应该共享相同的 io_service 引用,其生命周期应该比它们都长。否则你将需要每个连接一个线程,而且你最好不要打扰 asio...
  • 好的,谢谢您的建议。我会相应地改变我的班级。

标签: c++ sockets boost tcp boost-asio


【解决方案1】:

添加到@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)
{}

不同之处在于您的解析器、查询和套接字对象不再是“移动构造”的,而是直接构造的。根据您遇到的第二个错误,您似乎正在使用这些对象不可移动/可移动构造的 boost 版本(或者可能 boost 从未打算让这些类型可移动;不确定是哪个)。

如果您使用的是旧版本的 boost,请尝试更新到更高版本的库。不过,无论您是否愿意,您都需要更新代码,以便不再进行不必要的移动构建。

【讨论】:

  • 好收获。这就解释了所有与移动相关的错误,因为它只传递了右值。
  • @Minege 你必须澄清你的意思。您试图避免我展示的代码未处理的移动构造的哪些“属性”?
  • 我有 Boost 的最后一个版本,我使用了你展示的代码,它使用了对 ip 的引用,但它仍然无法正常工作。我对移动构造函数没有问题,但出现错误:没有匹配函数调用'boost::asio::ip::basic_resolver<:asio::ip::tcp>::basic_resolver(boost:: asio::io_service*)'
  • @Minege 我修复了代码。我忘记删除错误使用&amp; 来获取m_io_service 的地址,这是@Muscampester 的回答所讨论的。
  • 嗬,太棒了!它正在工作:)!谢谢 !现在,我真的不明白为什么它比我的第一个代码提议更好。您通过引用收到 IP args,您不再引用底层类型,但为什么这会更好?因为你直接从对象调用构造函数?你能像你说的那样给我一些关于“移动建筑”的链接吗?因为这似乎是把戏!谢谢!
【解决方案2】:

boost::asio::ip::basic_resolverconstructor 通过引用接受参数:

basic_resolver(boost::asio::io_service& io_service)

你已经获取了变量的地址并传递了一个指针:

m_resolver(tcp::resolver(&m_io_service))

尝试删除&amp;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-13
    • 2018-01-25
    • 1970-01-01
    • 2012-06-14
    • 2015-05-29
    • 1970-01-01
    • 2017-04-05
    • 1970-01-01
    相关资源
    最近更新 更多