Boost logo

Boost :

From: dmoore99atwork (dmoore_at_[hidden])
Date: 2002-01-22 21:55:57


> >4. Basic template question: One of my first experimental designs
> >was a templated "socket_address<>" class which I then explicitly
> >specialized for IPv4 and IPv6. Can someone point me to a best-
> >practices example *FOR CURRENT COMPILER TECHNOLOGY* for performing
> >explicit specialization? I think I understand the standard rules
ala
> >Stroustrup, but had a hard time finding common ground between gcc
and
> >MSVC 6.0. I didn't see anything in the Boost programming
guidelines
> >regarding this.
>
> Do you mean partial specialization? A bit more specific example
might be helpful.

Sorry to be imprecise. I meant "user specializations" as in section
13.5 of The C++ Programming language. I experimented with a design
where my fundamental socket_address class was templatized on protocol
type, and specialization would provide the particular hostname-to-
address resolution implementation.

Here is an abbreviated example with a templated class for
socket_addresses:

// socket_address.hpp
//

// Two "protocol_traits" structures used to select between
// partial specializations..

struct ipv4
{
  typedef sockaddr_in addr_type;
};

struct ipv6
{
  typedef sockaddr_in6 addr_type;
};

// Generic template, works for any
template<class Proto> class socket_address{
  public:
    socket_address(const char *hostname);
    operator sockaddr *(){return (sockaddr *) &_addr;}
  private:
    Proto::addr_type _addr;
};

// BEGIN QUESTIONABLE SECTION

// Declarations for explicit specializations for socket_address
//
// In MSVC 6.0, I could skip these *declarations*, and just
// provide the implementations in the .cpp file

template <> class socket_address<ipv4> {
  public:
    socket_address(const char *hostname);
    operator sockaddr *(){return (sockaddr *) &_addr;}
  private:
    ipv4::addr_type _addr;
};

template <> class socket_address<ipv6> {
  public:
    socket_address(const char *hostname);
    operator sockaddr *(){return (sockaddr *) &_addr;}
  private:
    ipv6::addr_type _addr;
};

// END QUESTIONABLE SECTION

// socket_address.cpp
// (must be included by .hpp for compilers not supporting
// seperate compilation of templates)

template<>
socket_address<ipv4>::
socket_address(const char *hostname)
{
  // use gethostbyname() to resolve the symbolic name
  // to an ipv4 sockaddr_in structure
}

template<>
socket_address<ipv6:::
socket_address(const char *hostname)
{
  // use getaddressinfo() to resolve the symbolic name
  // to an ipv6 sockaddr_in6 structure
}

With MSVC, I initiatally skipped the "QUESTIONABLE SECTION" in my
header file, and encountered no problems whatsoever.

With GCC 2.95 on Linux, if I tried to use the socket_address<ipv4>
class in another compilation unit, I got an error stating that the
compiler had already instantiated my specialization, and so my
specialization was rejected.

While I'm no longer sure that this design is even correct for
socket_addresses, I'm still curious as to the "best practices" for
user specializations. I don't necessarily want to place all of my
function implementations inline with the class declaration, but does
this mean I'm fighting compiler technology since I just wind up
having to #include my .cpp files on many platforms anyways? Should I
just always follow this form:

// generic.hpp
template<class T> class generic
{
   generic();
};

// declaration of specialization.
template<> class generic<subtype>
{
   generic();
};

// generic.cpp

template<class T>
generic<T>::
generic()
{
}

// and the specialization implementation
template<>
generic<subtype>::
generic()
{
}

 
> Good luck with this! And thanks to the others who started the ball
> rolling, but we just can't wait forever. Think about combining
forces if you are still interested.

Thanks - I'll need it! I think I can present a plausible set of
classes covering Win32 and Linux implementations of ipv4 sockets, and
a theoretical framework for ipv6. I will definitely need help on
other platforms and real-world ipv6 experience.

Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk