Как наследовать от boost :: asio :: streambuf после версии 1.70.0? - PullRequest
2 голосов
/ 28 марта 2020

После обновления boost версии 1.72.0, следующая программа, использующая boost :: asio, не может быть скомпилирована. Я заметил, что подпись read_until изменилась с версии 1.70.0.

Пример в Coliru

#include <iostream>
#include <boost/asio.hpp>

class framed_streambuf: public boost::asio::streambuf
{
};

int main()
{
    std::cout << "Using Boost "     
          << BOOST_VERSION / 100000     << "."  // major version
          << BOOST_VERSION / 100 % 1000 << "."  // minor version
          << BOOST_VERSION % 100                // patch level
          << std::endl;

    using boost::asio::ip::tcp;
    framed_streambuf streambuf;
    boost::asio::io_service io_service{1};
    tcp::socket client_socket(io_service);
    auto bytes_transferred = read_until(client_socket, streambuf, '@');

    return 0;
}

Ошибки компиляции:

/usr/local/include/boost/asio/impl/read_until.hpp: In instantiation of 'std::size_t boost::asio::read_until(SyncReadStream&, DynamicBuffer_v1&&, char, boost::system::error_code&, typename std::enable_if<(boost::asio::is_dynamic_buffer_v1<typename std::decay<_Func>::type>::value && (! boost::asio::is_dynamic_buffer_v2<typename std::decay<_Func>::type>::value))>::type*) [with SyncReadStream = boost::asio::basic_stream_socket<boost::asio::ip::tcp>; DynamicBuffer_v1 = framed_streambuf&; std::size_t = long unsigned int; typename std::enable_if<(boost::asio::is_dynamic_buffer_v1<typename std::decay<_Func>::type>::value && (! boost::asio::is_dynamic_buffer_v2<typename std::decay<_Func>::type>::value))>::type = void]':
/usr/local/include/boost/asio/impl/read_until.hpp:86:45:   required from 'std::size_t boost::asio::read_until(SyncReadStream&, DynamicBuffer_v1&&, char, typename std::enable_if<(boost::asio::is_dynamic_buffer_v1<typename std::decay<_Func>::type>::value && (! boost::asio::is_dynamic_buffer_v2<typename std::decay<_Func>::type>::value))>::type*) [with SyncReadStream = boost::asio::basic_stream_socket<boost::asio::ip::tcp>; DynamicBuffer_v1 = framed_streambuf&; std::size_t = long unsigned int; typename std::enable_if<(boost::asio::is_dynamic_buffer_v1<typename std::decay<_Func>::type>::value && (! boost::asio::is_dynamic_buffer_v2<typename std::decay<_Func>::type>::value))>::type = void]'
main.cpp:20:70:   required from here
/usr/local/include/boost/asio/impl/read_until.hpp:101:42: error: use of deleted function 'framed_streambuf::framed_streambuf(const framed_streambuf&)'
  101 |   typename decay<DynamicBuffer_v1>::type b(
      |                                          ^
main.cpp:4:7: note: 'framed_streambuf::framed_streambuf(const framed_streambuf&)' is implicitly deleted because the default definition would be ill-formed:
    4 | class framed_streambuf: public boost::asio::streambuf
      |       ^~~~~~~~~~~~~~~~
main.cpp:4:7: error: use of deleted function 'boost::asio::basic_streambuf<>::basic_streambuf(const boost::asio::basic_streambuf<>&)'
In file included from /usr/local/include/boost/asio.hpp:36,
                 from main.cpp:2:
/usr/local/include/boost/asio/basic_streambuf.hpp:111:7: note: 'boost::asio::basic_streambuf<>::basic_streambuf(const boost::asio::basic_streambuf<>&)' is implicitly deleted because the default definition would be ill-formed:
  111 | class basic_streambuf
      |       ^~~~~~~~~~~~~~~
/usr/local/include/boost/asio/basic_streambuf.hpp:111:7: error: 'boost::asio::detail::noncopyable::noncopyable(const boost::asio::detail::noncopyable&)' is private within this context
In file included from /usr/local/include/boost/asio/detail/std_fenced_block.hpp:23,
                 from /usr/local/include/boost/asio/detail/fenced_block.hpp:24,
                 from /usr/local/include/boost/asio/detail/executor_op.hpp:19,
                 from /usr/local/include/boost/asio/impl/system_executor.hpp:18,
                 from /usr/local/include/boost/asio/system_executor.hpp:129,
                 from /usr/local/include/boost/asio/associated_executor.hpp:21,
                 from /usr/local/include/boost/asio.hpp:21,
                 from main.cpp:2:
/usr/local/include/boost/asio/detail/noncopyable.hpp:32:3: note: declared private here
   32 |   noncopyable(const noncopyable&);
      |   ^~~~~~~~~~~
In file included from /usr/local/include/boost/asio/read_until.hpp:2795,
                 from /usr/local/include/boost/asio.hpp:114,
                 from main.cpp:2:
/usr/local/include/boost/asio/impl/read_until.hpp:108:59: error: 'framed_streambuf&' is not a class, struct, or union type
  108 |     typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;
      |                                                           ^~~~~~~~~~~~
/usr/local/include/boost/asio/impl/read_until.hpp:109:44: error: 'framed_streambuf&' is not a class, struct, or union type
  109 |     typedef buffers_iterator<buffers_type> iterator;

Начиная с boost 1.70.0, сигнатура read_until изменилась:

template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
    BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
    char delim, boost::system::error_code& ec,
    typename enable_if<
      is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
        && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
    >::type*)

Я знаю очень мало о enable_if, это имеет значение здесь?

...