Concerning Partial Template Specialization

Discussion in 'C++' started by Ioannis Gyftos, Jun 26, 2008.

  1. Hello,

    First the code :)


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


    namespace LJC{

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

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




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

    struct ConnectionType {
    struct Stream : public ConnectionTypeInterface
    {
    ...
    };
    struct Datagram : public ConnectionTypeInterface
    {
    ...
    };
    };

    .....

    }; // end of namespace




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




    template <
    class DomainInterface,
    class ConnectionTypeInterface
    >

    class Connection{
    public:

    Connection(const int port);
    Connection(const char* address);

    int init();

    private:
    DomainInterface Domain;
    ConnectionTypeInterface ConnectionType;
    };





    // This works.
    template <>
    inline Connection<
    LJC::Domain::Internet,
    LJC::ConnectionType::Datagram
    >::Connection(const char* a)

    {
    }





    // This works.
    template <
    class DomainInterface,
    class ConnectionTypeInterface
    >

    inline Connection<DomainInterface,
    ConnectionTypeInterface>::Connection(const char* a)
    {
    }





    // This does not work with the error message:
    // invalid use of incomplete type ‘class
    Connection<LJC::Domain::Internet, ConnectionTypeInterface>’
    // declaration of ‘class Connection<LJC::Domain::Internet,
    ConnectionTypeInterface>’
    template <
    class ConnectionTypeInterface
    >

    inline Connection<
    LJC::Domain::Internet,
    ConnectionTypeInterface
    >::Connection(const char* a)

    {
    }




    // This works
    template <
    class DomainInterface,
    class ConnectionTypeInterface
    >

    int Connection<DomainInterface, ConnectionTypeInterface>::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::Internet 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
    ConnectionTypeInterface>, 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 ConnectionTypeInterface
    >

    class Connection{
    public:

    Connection(const int port);
    Connection(const 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, Jun 26, 2008
    #1
    1. Advertising

  2. 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).
    Ioannis Gyftos, Jun 26, 2008
    #2
    1. Advertising

  3. On Jun 26, 4:17 pm, Ioannis Gyftos <> wrote:
    > 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).


    Hello again,

    Apparently I managed to figure out what the error was. A stumbled
    across a topic discussing *nested* template partial specialization
    which described better/clearer a situation similar to mine, and I
    could make a direct comparison.

    My error was that I hadn't partially specialized my base class (a
    thing which I tried, but my syntax was wrong - the example I found
    helped). to be precise, I had to add:

    template < class ConnectionTypeInterface >
    class Connection<LJC::Domain::Local, ConnectionTypeInterface>{
    ...
    }

    Now I'll use a base class and inherit the common subset of the
    functions that do not have to be specialized, as Victor Bazarov
    suggested somewhere.

    Sorry for the trouble, but I hope this might be helpful to someone in
    turn, and not just noise in the group.
    Ioannis Gyftos, Jun 27, 2008
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chandra Shekhar Kumar

    template partial specialization

    Chandra Shekhar Kumar, Jun 24, 2003, in forum: C++
    Replies:
    17
    Views:
    3,028
    tom_usenet
    Jun 25, 2003
  2. Joseph Turian
    Replies:
    2
    Views:
    464
  3. toton
    Replies:
    1
    Views:
    612
  4. vj
    Replies:
    1
    Views:
    482
  5. Hizo
    Replies:
    17
    Views:
    681
    itaj sherman
    Mar 7, 2011
Loading...

Share This Page