Search code examples
c++templatesboost-asiogeneric-programming

Overloadable boost::asio::basic_stream_socket


Developing a network application, I have a Connection class that manages sending and receiving messages on the network. I'm using boost::asio.

I now want to let the Connection class handle connections both over TCP, and over local UNIX stream sockets. However, the template-design of boost confuses me. AFAICT, there's no shared base-class between local::stream_protocol::socket and ip::tcp::socket.

How would I go about creating a Connection that encapsulates the network-semantics such that other code don't have to deal with the details of what protocol is used?

I.E. I want to implemented something like:

class Connection() {
  Connection(ip::tcp::endpoint& ep);
  Connection(local::stream_protocol::endpoint& ep);

  void send(Buffer& buf);
}

How would I achieve this?


Solution

  • After some pondering, my current solution is to make the send and recv functions of Connection virtual, and create a template-subclass of Connection, roughly:

    template <typename Protocol>
    class ConnectionImpl : public Connection {
        typedef typename Protocol::socket Socket;
        typedef typename Protocol::endpoint EndPoint;
    
        Socket _socket;
    public:
        ConnectionImpl(boost::asio::io_service& ioSvc, const EndPoint& addr) 
            : Connection(ioSvc), _socket(ioSvc) { 
            _socket.connect(addr);
        }
    
        void trySend() {
            // Initiate async send on _socket here
        }
    
        void tryRead() {
            // Initiate async recv on _socket here
        }
    }
    

    Is there a way to avoid the need to subclass and use of virtual functions?