Thread: Weird Conversion Error

  1. #1
    Registered User
    Join Date
    Jan 2014
    Posts
    139

    Weird Conversion Error

    I am trying to compile the example code located here libs/beast/example/http/server/small/http_server_small.cpp - 1.70.0 but I am getting an error right out of the box that I am unsure how to fix.

    The error occurs on this line below
    Code:
        // The timer for putting a deadline on connection processing.
        net::basic_waitable_timer<std::chrono::steady_clock> deadline_{
    
            socket_.get_executor(), std::chrono::seconds(60)};                          <-- error occurs here
    // Error
    Code:
    error: could not convert ‘{((http_connection*)this)->http_connection::socket_.boost::asio::basic_stream_socket<boost::asio::ip::tcp>::<anonymous>.boost::asio::basic_socket<boost::asio::ip::tcp>::get_executor(), std::chrono::duration<long int>(60)}’ from ‘<brace-enclosed initializer list>’ to ‘boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock>’
    Full Error
    Code:
    -------------- Build: Debug in TestBoostAsioBeast (compiler: GNU GCC Compiler)---------------
    
    
    g++ -Wall -fexceptions -g -Iinclude -c "/home/code/TestBoostAsioBeast/main.cpp" -o obj/Debug/main.o
    
    /home/code/TestBoostAsioBeast/main.cpp:94:57: error: could not convert ‘{((http_connection*)this)->http_connection::socket_.boost::asio::basic_stream_socket<boost::asio::ip::tcp>::<anonymous>.boost::asio::basic_socket<boost::asio::ip::tcp>::get_executor(), std::chrono::duration<long int>(60)}’ from ‘<brace-enclosed initializer list>’ to ‘boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock>’
    
             socket_.get_executor(), std::chrono::seconds(60)};
    
                                                             ^
    
    /home/code/TestBoostAsioBeast/main.cpp: In function ‘time_t ConvertStringToTimeTWithTimezone(std::__cxx11::string)’:
    
    /home/code/TestBoostAsioBeast/main.cpp:820:12: warning: unused variable ‘tCurrentTime2’ [-Wunused-variable]
    
         time_t tCurrentTime2 = mktime(&tmTime);
    
                ^~~~~~~~~~~~~
    
    /home/code/TestBoostAsioBeast/main.cpp: In function ‘int main()’:
    
    /home/code/TestBoostAsioBeast/main.cpp:1053:18: error: ‘do_session’ was not declared in this scope
    
                     &do_session,
    
                      ^~~~~~~~~~
    
    /home/code/TestBoostAsioBeast/main.cpp:1055:26: error: no matching function for call to ‘std::thread::thread(<brace-enclosed initializer list>)’
    
                     doc_root)}.detach();
    
                              ^
    
    In file included from /usr/include/c++/7/future:39:0,
    
                     from /usr/local/include/boost/asio/detail/future.hpp:20,
    
                     from /usr/local/include/boost/asio/packaged_task.hpp:19,
    
                     from /usr/local/include/boost/asio.hpp:101,
    
                     from /home/code/TestBoostAsioBeast/main.cpp:17:
    
    /usr/include/c++/7/thread:118:7: note: candidate: template<class _Callable, class ... _Args> std::thread::thread(_Callable&&, _Args&& ...)
    
           thread(_Callable&& __f, _Args&&... __args)
    
           ^~~~~~
    
    /usr/include/c++/7/thread:118:7: note:   template argument deduction/substitution failed:
    
    /usr/include/c++/7/thread:113:5: note: candidate: std::thread::thread(std::thread&&)
    
         thread(thread&& __t) noexcept
    
         ^~~~~~
    
    /usr/include/c++/7/thread:113:5: note:   conversion of argument 1 would be ill-formed:
    
    /usr/include/c++/7/thread:106:5: note: candidate: std::thread::thread()
    
         thread() noexcept = default;
    
         ^~~~~~
    
    /usr/include/c++/7/thread:106:5: note:   candidate expects 0 arguments, 1 provided
    
    Process terminated with status 1 (0 minute(s), 3 second(s))
    
    3 error(s), 1 warning(s) (0 minute(s), 3 second(s))


    Full Code
    Code:
    //
    // Copyright (c) 2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
    //
    // Distributed under the Boost Software License, Version 1.0. (See accompanying
    // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
    //
    // Official repository: GitHub - boostorg/beast: HTTP and WebSocket built on Boost.Asio in C++11
    //
    
    //------------------------------------------------------------------------------
    //
    // Example: HTTP server, small
    //
    //------------------------------------------------------------------------------
    
    #include <boost/beast/core.hpp>
    #include <boost/beast/http.hpp>
    #include <boost/beast/version.hpp>
    #include <boost/asio.hpp>
    #include <chrono>
    #include <cstdlib>
    #include <ctime>
    #include <iostream>
    #include <memory>
    #include <string>
    
    namespace beast = boost::beast;         // from <boost/beast.hpp>
    namespace http = beast::http;           // from <boost/beast/http.hpp>
    namespace net = boost::asio;            // from <boost/asio.hpp>
    using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
    
    namespace my_program_state
    {
        std::size_t
        request_count()
        {
            static std::size_t count = 0;
            return ++count;
        }
    
        std::time_t
        now()
        {
            return std::time(0);
        }
    }
    
    class http_connection : public std::enable_shared_from_this<http_connection>
    {
    public:
        http_connection(tcp::socket socket)
            : socket_(std::move(socket))
        {
        }
    
        // Initiate the asynchronous operations associated with the connection.
        void
        start()
        {
            read_request();
            check_deadline();
        }
    
    private:
        // The socket for the currently connected client.
        tcp::socket socket_;
    
        // The buffer for performing reads.
        beast::flat_buffer buffer_{8192};
    
        // The request message.
        http::request<http::dynamic_body> request_;
    
        // The response message.
        http::response<http::dynamic_body> response_;
    
        // The timer for putting a deadline on connection processing.
        net::basic_waitable_timer<std::chrono::steady_clock> deadline_{
            socket_.get_executor(), std::chrono::seconds(60)};
    
        // Asynchronously receive a complete request message.
        void
        read_request()
        {
            auto self = shared_from_this();
    
            http::async_read(
                socket_,
                buffer_,
                request_,
                [self](beast::error_code ec,
                    std::size_t bytes_transferred)
                {
                    boost::ignore_unused(bytes_transferred);
                    if(!ec)
                        self->process_request();
                });
        }
    
        // Determine what needs to be done with the request message.
        void
        process_request()
        {
            response_.version(request_.version());
            response_.keep_alive(false);
    
            switch(request_.method())
            {
            case http::verb::get:
                response_.result(http::status::ok);
                response_.set(http::field::server, "Beast");
                create_response();
                break;
    
            default:
                // We return responses indicating an error if
                // we do not recognize the request method.
                response_.result(http::status::bad_request);
                response_.set(http::field::content_type, "text/plain");
                beast::ostream(response_.body())
                    << "Invalid request-method '"
                    << std::string(request_.method_string())
                    << "'";
                break;
            }
    
            write_response();
        }
    
        // Construct a response message based on the program state.
        void
        create_response()
        {
            if(request_.target() == "/count")
            {
                response_.set(http::field::content_type, "text/html");
                beast::ostream(response_.body())
                    << "<html>\n"
                    <<  "<head><title>Request count</title></head>\n"
                    <<  "<body>\n"
                    <<  "<h1>Request count</h1>\n"
                    <<  "<p>There have been "
                    <<  my_program_state::request_count()
                    <<  " requests so far.</p>\n"
                    <<  "</body>\n"
                    <<  "</html>\n";
            }
            else if(request_.target() == "/time")
            {
                response_.set(http::field::content_type, "text/html");
                beast::ostream(response_.body())
                    <<  "<html>\n"
                    <<  "<head><title>Current time</title></head>\n"
                    <<  "<body>\n"
                    <<  "<h1>Current time</h1>\n"
                    <<  "<p>The current time is "
                    <<  my_program_state::now()
                    <<  " seconds since the epoch.</p>\n"
                    <<  "</body>\n"
                    <<  "</html>\n";
            }
            else
            {
                response_.result(http::status::not_found);
                response_.set(http::field::content_type, "text/plain");
                beast::ostream(response_.body()) << "File not found\r\n";
            }
        }
    
        // Asynchronously transmit the response message.
        void
        write_response()
        {
            auto self = shared_from_this();
    
            response_.set(http::field::content_length, response_.body().size());
    
            http::async_write(
                socket_,
                response_,
                [self](beast::error_code ec, std::size_t)
                {
                    self->socket_.shutdown(tcp::socket::shutdown_send, ec);
                    self->deadline_.cancel();
                });
        }
    
        // Check whether we have spent enough time on this connection.
        void
        check_deadline()
        {
            auto self = shared_from_this();
    
            deadline_.async_wait(
                [self](beast::error_code ec)
                {
                    if(!ec)
                    {
                        // Close socket to cancel any outstanding operation.
                        self->socket_.close(ec);
                    }
                });
        }
    };
    
    // "Loop" forever accepting new connections.
    void
    http_server(tcp::acceptor& acceptor, tcp::socket& socket)
    {
      acceptor.async_accept(socket,
          [&](beast::error_code ec)
          {
              if(!ec)
                  std::make_shared<http_connection>(std::move(socket))->start();
              http_server(acceptor, socket);
          });
    }
    
    int
    main(int argc, char* argv[])
    {
        try
        {
            // Check command line arguments.
            if(argc != 3)
            {
                std::cerr << "Usage: " << argv[0] << " <address> <port>\n";
                std::cerr << "  For IPv4, try:\n";
                std::cerr << "    receiver 0.0.0.0 80\n";
                std::cerr << "  For IPv6, try:\n";
                std::cerr << "    receiver 0::0 80\n";
                return EXIT_FAILURE;
            }
    
            auto const address = net::ip::make_address(argv[1]);
            unsigned short port = static_cast<unsigned short>(std::atoi(argv[2]));
    
            net::io_context ioc{1};
    
            tcp::acceptor acceptor{ioc, {address, port}};
            tcp::socket socket{ioc};
            http_server(acceptor, socket);
    
            ioc.run();
        }
        catch(std::exception const& e)
        {
            std::cerr << "Error: " << e.what() << std::endl;
            return EXIT_FAILURE;
        }
    }

    Thanks for any help you can provide!
    Last edited by EverydayDiesel; 06-08-2019 at 04:12 PM.

  2. #2
    Registered User
    Join Date
    May 2019
    Posts
    214
    Best I can tell from a quick look is that asio underwent changes and there are a few notes on their github indicating they changed asio.

    There were lots of discussions about how things are constructed/initialized, as this line does, which broke older code examples.

    I tried with 1.69 & 1.68, but this example issues the same or similar error.

    It would appear the example may be outdated (even if it came with 1.7). The github discussion (boost) indicates that for a while the builds were broken in 1.7 (possibly older ones too) and they "fixed" it, but the fix does not apply to older example builds, but of new ways to instantiate/open objects.

    In other words, they changed the API a bit (it seems).

    This may work with an older version of boost, but more recent that 1.61 (the oldest I have, which does not have beast). So, you could try the first version were beast was added and work forward with a few versions if you prefer, otherwise you'll probably have to find a more current example (or fix this one - by starting it over through a tutorial/study of asio).

    Asio is worth the trouble, and it is (or has) been considered for submission to the C++ standard library around C++20, but that may be the problem - they may be dressing it up and dealing with "issues" related to that submission (I'm guessing).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. weird error
    By ExDHaos in forum C++ Programming
    Replies: 4
    Last Post: 05-16-2009, 05:49 PM
  2. Weird error
    By lolguy in forum C Programming
    Replies: 11
    Last Post: 01-21-2009, 03:30 AM
  3. Say what? - Weird error.
    By Blackroot in forum C++ Programming
    Replies: 6
    Last Post: 08-15-2006, 11:54 PM
  4. Weird Error. Please Help.
    By RP319 in forum C++ Programming
    Replies: 2
    Last Post: 02-19-2006, 09:33 PM
  5. weird error
    By gandalf_bar in forum Linux Programming
    Replies: 2
    Last Post: 07-17-2005, 07:32 AM

Tags for this Thread