Concerning Partial Template Specialization

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ioannis Gyftos

    Concerning Partial Template Specialization

    Hello,

    First the code :)


    ///////////////////////////////////////////////////////////////////////////////////
    // in another header file


    namespace LJC{

    struct DomainInterface {
    ... // pure virtual functions
    };

    struct ConnectionTypeI nterface {
    ... // pure virtual functions
    };




    struct Domain {
    struct Local : public DomainInterface
    {
    ...
    };
    struct Internet : public DomainInterface
    {
    ...
    };
    };

    struct ConnectionType {
    struct Stream : public ConnectionTypeI nterface
    {
    ...
    };
    struct Datagram : public ConnectionTypeI nterface
    {
    ...
    };
    };

    .....

    }; // end of namespace




    ///////////////////////////////////////////////////////////////////////////////////




    template <
    class DomainInterface ,
    class ConnectionTypeI nterface
    >
    class Connection{
    public:

    Connection(cons t int port);
    Connection(cons t char* address);

    int init();

    private:
    DomainInterface Domain;
    ConnectionTypeI nterface ConnectionType;
    };





    // This works.
    template <>
    inline Connection<
    LJC::Domain::In ternet,
    LJC::Connection Type::Datagram
    >::Connection(c onst char* a)
    {
    }





    // This works.
    template <
    class DomainInterface ,
    class ConnectionTypeI nterface
    >
    inline Connection<Doma inInterface,
    ConnectionTypeI nterface>::Conn ection(const char* a)
    {
    }





    // This does not work with the error message:
    // invalid use of incomplete type ‘class
    Connection<LJC: :Domain::Intern et, ConnectionTypeI nterface>’
    // declaration of ‘class Connection<LJC: :Domain::Intern et,
    ConnectionTypeI nterface>’
    template <
    class ConnectionTypeI nterface
    >
    inline Connection<
    LJC::Domain::In ternet,
    ConnectionTypeI nterface
    >::Connection(c onst char* a)
    {
    }




    // This works
    template <
    class DomainInterface ,
    class ConnectionTypeI nterface
    >
    int Connection<Doma inInterface, ConnectionTypeI nterface>::init ()
    {
    }


    ///////////////////////////////////////////////////////////////////////////////////



    To give some background on what I am trying to do:
    I have recently created some TCP, UDP and UnixSocket libraries with
    very similar interface for different projects. After getting inspired
    by Alexandrescu's book, I was trying to combine those in a single
    templated 'Connection' class, which would use such templates to define
    protocols and policies (like server/client, blocking/non-blocking
    function calls). The general flow of either of these combination is
    similar, so I figured I would train myself into creating something
    like this.

    The specific problem I was trying to solve is the constructor call. A
    class instantiated with Domain::Local should be constructed with a
    const char* (socket path), but a class instantiated with
    Domain::Interne t should use an integer (port). To solve this, I though
    I would create two constructors, one with char* and one with int. I
    would implement a partial template specialization for <Internet,int >
    and one for <Local,char*> , so if a user would call it with correct
    combination it would work, but if he tried to call a wrong one it
    would throw a compiler undefined reference error.

    I looked around the web, some books etc, but I could not understand
    why am I getting this error. I can use the constructor unspecialized
    or fully specialized, but not partially. Full specialization is not
    really acceptable since I plan to add more template parameters later
    (starting of slow). Most examples I found on the net use ints or bools
    while partially specializing, I tried with those but I got the same
    result (I am saying this because I stumbled across someone mentioning
    that I couldn't use a class for specialization, but I am confused
    about what he meant).

    I also read something else on the net, which I did not fully
    understand; the partial specialization failed because the top-level
    class is templated for <class DomainInterface , class
    ConnectionTypeI nterface>, and there is no top-level class
    specialization for the partial-specialized case. Following this, I
    tried (with several combinations) something like this:

    template <
    class ConnectionTypeI nterface
    >
    class Connection{
    public:

    Connection(cons t int port);
    Connection(cons t char* address);
    ....
    };

    But I got redefinition error messages.

    Can what I describe above be done? If so, what is my mistake and how
    can it be corrected? My C++ intuition so far tells me that it does,
    but if it's impossible, I haven't thought of a secondary plan so far,
    so I might ask later on :P
  • Ioannis Gyftos

    #2
    Re: Concerning Partial Template Specialization

    Apparently, the Google groups have eaten some ">" that end the
    template parameter lists when on a single line.

    (And by the way, I use gcc 4.3.0, and the manpage didn't mention
    anything about not supporting partial specializations , so I think/hope
    it's not a compiler error).

    Comment

    Working...