Opened 5 years ago

Last modified 4 years ago

#13291 new Bugs

read_until won't compile with Visual Studio 2017 using regex

Reported by: Ville-Pekka Vahteala <vahtis@…> Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.66.0 Severity: Showstopper
Keywords: asio, regex Cc:

Description

Compiling following code will produce compiler error

#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/read_until.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/regex.hpp>

int main() {
	boost::asio::io_service ios;
	boost::asio::ip::tcp::socket s(ios);
	boost::asio::streambuf b;
	boost::system::error_code e;
	boost::asio::read_until(s, b, boost::regex("i am just a regex"), e);
}
1>d:\source\boost\boost\asio\impl\read_until.hpp(273): error C2664: 'size_t boost::asio::basic_streambuf<std::allocator<char>>::read_size_helper(boost::asio::basic_streambuf<std::allocator<char>> &,::size_t)': cannot convert argument 1 from 'boost::asio::basic_streambuf_ref<Allocator>' to 'boost::asio::basic_streambuf<std::allocator<char>> &'
1>        with
1>        [
1>            Allocator=std::allocator<char>
1>        ]
1>d:\source\boost\boost\asio\impl\read_until.hpp(404): note: see reference to function template instantiation 'size_t boost::asio::read_until<SyncReadStream,boost::asio::basic_streambuf_ref<Allocator>>(SyncReadStream &,DynamicBuffer &&,const boost::regex &,boost::system::error_code &)' being compiled
1>        with
1>        [
1>            SyncReadStream=boost::asio::ip::tcp::socket,
1>            Allocator=std::allocator<char>,
1>            DynamicBuffer=boost::asio::basic_streambuf_ref<std::allocator<char>>
1>        ]
1>c:\users\????\error.cpp(12): note: see reference to function template instantiation 'size_t boost::asio::read_until<boost::asio::ip::tcp::socket,std::allocator<char>>(SyncReadStream &,boost::asio::basic_streambuf<std::allocator<char>> &,const boost::regex &,boost::system::error_code &)' being compiled
1>        with
1>        [
1>            SyncReadStream=boost::asio::ip::tcp::socket
1>        ]

This can be solved by using same calculation as other methods use

    // Need more data.
	std::size_t bytes_to_read = std::min<std::size_t>(
		std::max<std::size_t>(512, b.capacity() - b.size()),
		std::min<std::size_t>(65536, b.max_size() - b.size()));

instead of

    std::size_t bytes_to_read = read_size_helper(b, 65536);

Change History (1)

comment:1 by Eric Müller <mueller@…>, 4 years ago

I also encountered this issue, and overloading the friended read_size_helper (taking basic_streambuf as the first parameter) for basic_streambuf_ref (in boost/asio/basic_streambuf.hpp) might be a fix:

/// Adapts basic_streambuf to the dynamic buffer sequence type requirements.
#if defined(GENERATING_DOCUMENTATION)
template <typename Allocator = std::allocator<char> >
#else
template <typename Allocator>
#endif
class basic_streambuf_ref
{
// ...
private:
  friend std::size_t read_size_helper(
      basic_streambuf_ref& sb, std::size_t max_size)
  {
    return read_size_helper(sb.sb_, max_size);
  }
};
Note: See TracTickets for help on using tickets.