0

I am having trouble compiling with boost library with boost.asio.

I am trying to create a boost-udp socket from my class constructor. I tried few different things to compile, but still I am seeing the issue.

Does anyone has clue on this issue? Can anyone help me with the mistake, I am doing?

Here is my class:

    class NetworkTestToolServer
    {
        private:
            boost::asio::io_service*       my_io_service;
            boost::asio::ip::udp::endpoint server_endpoint;
            boost::asio::ip::udp::socket   server_udp_socket;
            boost::asio::ip::udp::endpoint sender_endpoint;
            boost::asio::ip::udp::endpoint client_endpoint;
        public:
            NetworkTestToolServer(short port);
    };

Here is my constructor, I am using (failing at server_udp_socket):

NetworkTestToolServer::NetworkTestToolServer(short port)
{
    my_io_service = new boost::asio::io_service();

    server_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(),
                                                     50002);

    server_udp_socket = boost::asio::ip::udp::socket(*my_io_service, 
                                                     server_endpoint);
}

I am seeing the following error:

user2@user2-VirtualBox:~/network_test_tool/network-test-tool/build$ make
[ 20%] Built target gmock_main
[ 35%] Built target gmock
[ 45%] Built target gtest
[ 55%] Built target gtest_main
Scanning dependencies of target network-test-tool-lib
[ 60%] Building CXX object app/CMakeFiles/network-test-tool-lib.dir/src/ntt/NetworkTestToolServer.cpp.o                                                                                         
/home/user2/network_test_tool/network-test-tool/app/src/ntt/NetworkTestToolServer.cpp: In constructor ‘ntt::NetworkTestToolServer::NetworkTestToolServer(short int)’:
/home/user2/network_test_tool/network-test-tool/app/src/ntt/NetworkTestToolServer.cpp:34:56: error: no matching function for call to ‘boost::asio::basic_datagram_socket<boost::asio::ip::udp>::basic_datagram_socket()’
 NetworkTestToolServer::NetworkTestToolServer(short port)
                                                        ^
In file included from /usr/include/boost/asio.hpp:21:0,
                 from /home/user2/network_test_tool/network-test-tool/app/src/ntt/NetworkTestToolServer.cpp:3:
/usr/include/boost/asio/basic_datagram_socket.hpp:183:3: note: candidate: template<class Protocol1, class DatagramSocketService1> boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::basic_datagram_socket(boost::asio::basic_datagram_socket<Protocol1, DatagramSocketService1>&&, typename std::enable_if<std::is_convertible<Protocol1, Protocol>::value>::type*)
   basic_datagram_socket(
   ^~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/asio/basic_datagram_socket.hpp:183:3: note:   template argument deduction/substitution failed:
/home/user2/network_test_tool/network-test-tool/app/src/ntt/NetworkTestToolServer.cpp:34:56: note:   candidate expects 2 arguments, 0 provided
 NetworkTestToolServer::NetworkTestToolServer(short port)
                                                        ^
In file included from /usr/include/boost/asio.hpp:21:0,
                 from /home/user2/network_test_tool/network-test-tool/app/src/ntt/NetworkTestToolServer.cpp:3:
/usr/include/boost/asio/basic_datagram_socket.hpp:147:3: note: candidate: boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::basic_datagram_socket(boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>&&) [with Protocol = boost::asio::ip::udp; DatagramSocketService = boost::asio::datagram_socket_service<boost::asio::ip::udp>]
   basic_datagram_socket(basic_datagram_socket&& other)
   ^~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/asio/basic_datagram_socket.hpp:147:3: note:   candidate expects 1 argument, 0 provided
/usr/include/boost/asio/basic_datagram_socket.hpp:129:3: note: candidate: boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::basic_datagram_socket(boost::asio::io_service&, const protocol_type&, const native_handle_type&) [with Protocol = boost::asio::ip::udp; DatagramSocketService = boost::asio::datagram_socket_service<boost::asio::ip::udp>; boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::protocol_type = boost::asio::ip::udp; boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::native_handle_type = int]
   basic_datagram_socket(boost::asio::io_service& io_service,
   ^~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/asio/basic_datagram_socket.hpp:129:3: note:   candidate expects 3 arguments, 0 provided
/usr/include/boost/asio/basic_datagram_socket.hpp:108:3: note: candidate: boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::basic_datagram_socket(boost::asio::io_service&, const endpoint_type&) [with Protocol = boost::asio::ip::udp; DatagramSocketService = boost::asio::datagram_socket_service<boost::asio::ip::udp>; boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::endpoint_type = boost::asio::ip::basic_endpoint<boost::asio::ip::udp>]
   basic_datagram_socket(boost::asio::io_service& io_service,
   ^~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/asio/basic_datagram_socket.hpp:108:3: note:   candidate expects 2 arguments, 0 provided
/usr/include/boost/asio/basic_datagram_socket.hpp:86:3: note: candidate: boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::basic_datagram_socket(boost::asio::io_service&, const protocol_type&) [with Protocol = boost::asio::ip::udp; DatagramSocketService = boost::asio::datagram_socket_service<boost::asio::ip::udp>; boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::protocol_type = boost::asio::ip::udp]
   basic_datagram_socket(boost::asio::io_service& io_service,
   ^~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/asio/basic_datagram_socket.hpp:86:3: note:   candidate expects 2 arguments, 0 provided
/usr/include/boost/asio/basic_datagram_socket.hpp:69:12: note: candidate: boost::asio::basic_datagram_socket<Protocol, DatagramSocketService>::basic_datagram_socket(boost::asio::io_service&) [with Protocol = boost::asio::ip::udp; DatagramSocketService = boost::asio::datagram_socket_service<boost::asio::ip::udp>]
   explicit basic_datagram_socket(boost::asio::io_service& io_service)
            ^~~~~~~~~~~~~~~~~~~~~
/usr/include/boost/asio/basic_datagram_socket.hpp:69:12: note:   candidate expects 1 argument, 0 provided
app/CMakeFiles/network-test-tool-lib.dir/build.make:110: recipe for target 'app/CMakeFiles/network-test-tool-lib.dir/src/ntt/NetworkTestToolServer.cpp.o' failed
make[2]: *** [app/CMakeFiles/network-test-tool-lib.dir/src/ntt/NetworkTestToolServer.cpp.o] Error 1
CMakeFiles/Makefile2:1228: recipe for target 'app/CMakeFiles/network-test-tool-lib.dir/all' failed
make[1]: *** [app/CMakeFiles/network-test-tool-lib.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
user2@user2-VirtualBox:~/network_test_tool/network-test-tool/build$ 
craigcaulfield
  • 3,381
  • 10
  • 32
  • 40
Krishna
  • 11
  • 1

1 Answers1

0

https://www.boost.org/doc/libs/1_67_0/doc/html/boost_asio/reference/basic_datagram_socket/basic_datagram_socket.html

udp::socket doesn't have a default constructor. Your constructor is,

NetworkTestToolServer::NetworkTestToolServer(short port)
{
    my_io_service = new boost::asio::io_service();

    server_endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(),
                                                     50002);

    server_udp_socket = boost::asio::ip::udp::socket(*my_io_service, 
                                                     server_endpoint);
}

This is a very poor way of writing constructors. The constructor will call default constructor for every member in the class. In your case, udp::socket doesn't have a default constructor. That's why it fails to compile. Only after default construction the statement in the braces block are executed. What you need is member initializer list. For more reference, see this stackoverflow question.

What you want is something like this,

class NetworkTestToolServer
{
    using udp = boost::asio::ip::udp;
    private:
        boost::asio::io_service*       my_io_service;
        udp::endpoint server_endpoint;
        udp::socket   server_udp_socket;
        udp::endpoint sender_endpoint;
        udp::endpoint client_endpoint;
    public:
        NetworkTestToolServer(short port);
};

NetworkTestToolServer::NetworkTestToolServer(short port)
  : my_io_service(new boost::asio::io_service),
    server_endpoint(udp::endpoint(udp::v4(), port)),
    server_udp_socket(udp::socket(*my_io_service, server_endpoint))
{
}

It's unfortunate that gcc does not produce very good error code. clang gives much better error,

udp_bad.cpp:15:24: error: constructor for 'NetworkTestToolServer' must explicitly initialize the member 'server_udp_socket' which does not have a default constructor
NetworkTestToolServer::NetworkTestToolServer(short port)

Try multiple compilers next time.

MaxPlankton
  • 1,158
  • 14
  • 28
  • Thanks for your answer. It is very helpful. How can we determine, if a class has 'default' constructor or not ? In this case, how do we know, whether 'udp::socket' has default constructor or not. Is this documented somewhere ? I could not find about this in boost documentation – Krishna May 16 '18 at 13:26
  • Read the link I posted above. All constructors are listed. There's no constructor taking zero arugments or default arguments. So it couldn't be default constructed. You can try create a simple class like `Class Test { Test(int i) {} };` and check if you can create a instance of `Test` by calling `Test()`. There's a way to determine if a class can be default constructed. For a type `T`, check if `std::is_default_constructible::value` returns true or false. – MaxPlankton May 16 '18 at 15:08
  • I am not trying to discourage you. Boost asio is not a simple library to learn. If you don't understand C++ basics like default constructor, it will be really, really hard. Anyway, ganbade! – MaxPlankton May 16 '18 at 15:11