使用参数<boost :: asio :: ip :: tcp :: socket>将std :: bind应用于函数时出错?

时间:2018-05-20 08:35:09

标签: c++ boost c++14

接受类型为boost::asio::ip::tcp::socket的参数的函数。但我没有将std :: bind应用于它。我在std :: _ Bind_helper中检查了模板参数,但没有发现问题。我已经尝试了gcc 8.1.0和clang 6.0.0,他们也给出了同样的错误。

#include <functional>
#include <boost/asio.hpp>
using namespace std;
namespace asio = boost::asio;
using tcp = asio::ip::tcp;

int c;

void good_f(int) {c=1;}
void good() {
    using typeA = int;

    auto helper = std::bind(&good_f, typeA(1));
    helper();
    // OK
}

void fixed_f(tcp::socket &) {c=1;}
void fixed() {
    using type1 = tcp::socket;
    asio::io_context ioc;
    tcp::socket sock(ioc);

    auto helper = std::bind(&fixed_f, std::ref(sock));
    helper();
    // OK
}

void fail_f(tcp::socket &&) {c=1;}
void fail() {
    using type1 = tcp::socket;
    asio::io_context ioc;
    tcp::socket sock(ioc);

    // fail_f(std::move(sock));
    // OK

    auto helper = std::bind(&fail_f, std::move(sock));
    helper();
    // a.cc:34:5: error: no matching function for call to object of type 'std::_Bind<void (*(boost::asio::basic_stream_socket<boost::asio::ip::tcp>))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
    //    helper();
    //    ^~~~~~
}

编译日志和错误:

recolic@RECOLICPC ~/tmp> clang++ --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
recolic@RECOLICPC ~/tmp> clang++ -c a.cc
a.cc:39:5: error: no matching function for call to object of type 'std::_Bind<void (*(boost::asio::basic_stream_socket<boost::asio::ip::tcp>))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
    helper();
    ^~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:480:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void
      (*&(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
        operator()(_Args&&... __args)
        ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:491:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void (*const &(const
      boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
        operator()(_Args&&... __args) const
        ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:509:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void (*volatile &(volatile
      boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
        operator()(_Args&&... __args) volatile
        ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/8.1.0/../../../../include/c++/8.1.0/functional:521:2: note: candidate template ignored: substitution failure [with _Args = <>]: no type named 'type' in 'std::result_of<void (*const volatile &(const volatile
      boost::asio::basic_stream_socket<boost::asio::ip::tcp> &))(boost::asio::basic_stream_socket<boost::asio::ip::tcp> &&)>'
        operator()(_Args&&... __args) const volatile
        ^
1 error generated.

我不确定导致此错误的原因。你能给我任何建议吗?

1 个答案:

答案 0 :(得分:1)

void fail_f_1(tcp::socket); std::bind(&fail_f_1, tcp::socket(io_context)); 此解决方案失败,因为boost::asio::ip::tcp::socket是不可复制的。

void fail_f_2(tcp::socket &&); std::bind(&fail_f_2, std::move(tcp::socket(io_context))); 此解决方案失败,因为std::bind将绑定参数作为左值而非rvalue传递。 fixed_f是一个很好的解决方案。

如果必须将rvalue-reference作为绑定参数传递,this answer将有所帮助。