Templating a typedef or aliasing a template

Discussion in 'C++' started by Michal Nazarewicz, Nov 12, 2006.

  1. Let say I have a class template Set which represent set of objects of
    given type, and a struct template Pair representing an ordered pair,
    ie:

    #v+
    template<class T>
    class Set {
    /* ... whatever ... */
    public:
    bool exists(const T &element) { /* ... */ }
    Set<T> &add (const T &element) { /* ... */ return *this; }
    Set<T> &remove(const T &element) { /* ... */ return *this; }
    void union (const Set<T> &set) { /* ... */ }
    };

    template<class T>
    struct Pair {
    T left, right;
    };
    #v-

    Now, I want to create an "alias template" Relation<T> (representing a
    binary relation) to mean Set< Pair<T> >. Unfortunately,
    `template<class T> typedef Set< Pair<T> > Relation<T>;' won't work, so
    I had to define something like:

    #v+
    template<class T> class Relation : public Set< Pair<T> > { };
    #v-

    but then add() and remove() methods would return reference to
    Set<Pair<T> > which is not the same type as Relation<T> so I'd have to
    create class template like:

    #v+
    template<class T>
    class Relation {
    Set< Pair<T> > set;
    public:
    bool exists(const Pair<T> &pair) {
    return set.exists(pair);
    }
    Relation<T> &add (const Pair<T> &pair) {
    set.add(pair); return *this;
    }
    Relation<T> &remove(const Pair<T> &pair) {
    set.remove(pair); return *this;
    }
    void union (const Relation<T> &rel) {
    set.union(rel.set);
    }
    };
    #v-

    ie. for each method from Set class I'd have to create method in
    Relation class. It seems to me like a lot of useless code plus still
    Relation<T> and Set< Pair<T> > are two different types so I wouldn't
    be able to do:

    #v+
    Set< Pair<T> > set;
    Relation<T> rel;
    set.union(rel);
    #v-

    unless I define an operator const Set< Pair<T> >() and that's just
    another piece of useless code.

    Is then any nice and easy way to create a nice alias so user wouldn't
    have to type Set< Pair<T> > but rather Relation<T>?

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
    Michal Nazarewicz, Nov 12, 2006
    #1
    1. Advertising

  2. Michal Nazarewicz

    Guest

    Michal Nazarewicz wrote:
    > Let say I have a class template Set which represent set of objects of
    > given type, and a struct template Pair representing an ordered pair,
    > ie:
    >
    > #v+
    > template<class T>
    > class Set {
    > /* ... whatever ... */
    > public:
    > bool exists(const T &element) { /* ... */ }
    > Set<T> &add (const T &element) { /* ... */ return *this; }
    > Set<T> &remove(const T &element) { /* ... */ return *this; }
    > void union (const Set<T> &set) { /* ... */ }
    > };
    >
    > template<class T>
    > struct Pair {
    > T left, right;
    > };
    > #v-
    >
    > Now, I want to create an "alias template" Relation<T> (representing a
    > binary relation) to mean Set< Pair<T> >. Unfortunately,
    > `template<class T> typedef Set< Pair<T> > Relation<T>;' won't work, so
    > I had to define something like:
    >
    > #v+
    > template<class T> class Relation : public Set< Pair<T> > { };
    > #v-
    >
    > but then add() and remove() methods would return reference to
    > Set<Pair<T> > which is not the same type as Relation<T> so I'd have to
    > create class template like:
    >
    > #v+
    > template<class T>
    > class Relation {
    > Set< Pair<T> > set;
    > public:
    > bool exists(const Pair<T> &pair) {
    > return set.exists(pair);
    > }
    > Relation<T> &add (const Pair<T> &pair) {
    > set.add(pair); return *this;
    > }
    > Relation<T> &remove(const Pair<T> &pair) {
    > set.remove(pair); return *this;
    > }
    > void union (const Relation<T> &rel) {
    > set.union(rel.set);
    > }
    > };
    > #v-
    >
    > ie. for each method from Set class I'd have to create method in
    > Relation class. It seems to me like a lot of useless code plus still
    > Relation<T> and Set< Pair<T> > are two different types so I wouldn't
    > be able to do:
    >
    > #v+
    > Set< Pair<T> > set;
    > Relation<T> rel;
    > set.union(rel);
    > #v-
    >
    > unless I define an operator const Set< Pair<T> >() and that's just
    > another piece of useless code.
    >
    > Is then any nice and easy way to create a nice alias so user wouldn't
    > have to type Set< Pair<T> > but rather Relation<T>?
    >




    Hi,
    Maybe I am missing something, but I don't see anythin wrong woth your
    first proposed method.

    template<class T> class Relation : public Set< Pair<T> > { };

    For all intent an purposes this derived class will act exactly like its
    Base, theres no difference, well almost. The only time I think you will
    have an issue is any function that takes by value or retuns by value
    Set<Pair<T> >. I use this method for typedefing templates and never had
    a problem with it. When referring by pointer or reference there is no
    difference, well none that I can see.

    N
    , Nov 12, 2006
    #2
    1. Advertising

  3. Michal Nazarewicz

    Guest

    wrote:
    > Michal Nazarewicz wrote:
    > > Let say I have a class template Set which represent set of objects of
    > > given type, and a struct template Pair representing an ordered pair,
    > > ie:
    > >
    > > #v+
    > > template<class T>
    > > class Set {
    > > /* ... whatever ... */
    > > public:
    > > bool exists(const T &element) { /* ... */ }
    > > Set<T> &add (const T &element) { /* ... */ return *this; }
    > > Set<T> &remove(const T &element) { /* ... */ return *this; }
    > > void union (const Set<T> &set) { /* ... */ }
    > > };
    > >
    > > template<class T>
    > > struct Pair {
    > > T left, right;
    > > };
    > > #v-
    > >
    > > Now, I want to create an "alias template" Relation<T> (representing a
    > > binary relation) to mean Set< Pair<T> >. Unfortunately,
    > > `template<class T> typedef Set< Pair<T> > Relation<T>;' won't work, so
    > > I had to define something like:
    > >
    > > #v+
    > > template<class T> class Relation : public Set< Pair<T> > { };
    > > #v-
    > >
    > > but then add() and remove() methods would return reference to
    > > Set<Pair<T> > which is not the same type as Relation<T> so I'd have to
    > > create class template like:
    > >
    > > #v+
    > > template<class T>
    > > class Relation {
    > > Set< Pair<T> > set;
    > > public:
    > > bool exists(const Pair<T> &pair) {
    > > return set.exists(pair);
    > > }
    > > Relation<T> &add (const Pair<T> &pair) {
    > > set.add(pair); return *this;
    > > }
    > > Relation<T> &remove(const Pair<T> &pair) {
    > > set.remove(pair); return *this;
    > > }
    > > void union (const Relation<T> &rel) {
    > > set.union(rel.set);
    > > }
    > > };
    > > #v-
    > >
    > > ie. for each method from Set class I'd have to create method in
    > > Relation class. It seems to me like a lot of useless code plus still
    > > Relation<T> and Set< Pair<T> > are two different types so I wouldn't
    > > be able to do:
    > >
    > > #v+
    > > Set< Pair<T> > set;
    > > Relation<T> rel;
    > > set.union(rel);
    > > #v-
    > >
    > > unless I define an operator const Set< Pair<T> >() and that's just
    > > another piece of useless code.
    > >
    > > Is then any nice and easy way to create a nice alias so user wouldn't
    > > have to type Set< Pair<T> > but rather Relation<T>?
    > >

    >
    >
    >
    > Hi,
    > Maybe I am missing something, but I don't see anythin wrong woth your
    > first proposed method.
    >
    > template<class T> class Relation : public Set< Pair<T> > { };
    >
    > For all intent an purposes this derived class will act exactly like its
    > Base, theres no difference, well almost. The only time I think you will
    > have an issue is any function that takes by value or retuns by value
    > Set<Pair<T> >. I use this method for typedefing templates and never had
    > a problem with it. When referring by pointer or reference there is no
    > difference, well none that I can see.
    >


    PS ... what I will add, you didn't have anything but the compiler
    provided default and copy constructors and the compiler provided
    assignement operator in you Set class. If this was not the case you
    would have to provide your derived class with the neccessary
    constructors and the assignment operator is not inheritable.
    , Nov 12, 2006
    #3
  4. Michal Nazarewicz

    dasjotre Guest

    Michal Nazarewicz wrote:
    > Let say I have a class template Set which represent set of objects of
    > given type, and a struct template Pair representing an ordered pair,
    > ie:

    you basically want a template typedef?

    if so:

    template<class T>
    struct Relation_typedef
    {
    typedef Set< Pair<T> > Relation;
    };

    and use it as Relation_typedef<real type>::Relation
    instead of Set<Pair<real type> >
    dasjotre, Nov 13, 2006
    #4
  5. > Michal Nazarewicz wrote:
    >> Let say I have a class template Set which represent set of objects of
    >> given type, and a struct template Pair representing an ordered pair,
    >> ie:
    >>
    >> #v+
    >> template<class T>
    >> class Set {
    >> /* ... whatever ... */
    >> public:
    >> bool exists(const T &element) { /* ... */ }
    >> Set<T> &add (const T &element) { /* ... */ return *this; }
    >> Set<T> &remove(const T &element) { /* ... */ return *this; }
    >> void union (const Set<T> &set) { /* ... */ }
    >> };
    >>
    >> template<class T>
    >> struct Pair { T left, right; };
    >> #v-
    >>
    >> Now, I want to create an "alias template" Relation<T> (representing a
    >> binary relation) to mean Set< Pair<T> >.

    [...]

    writes:
    > Maybe I am missing something, but I don't see anythin wrong woth your
    > first proposed method.
    >
    > template<class T> class Relation : public Set< Pair<T> > { };
    >
    > For all intent an purposes this derived class will act exactly like its
    > Base, theres no difference, well almost. The only time I think you will
    > have an issue is any function that takes by value or retuns by value
    > Set<Pair<T> >.


    Ah, and that's my concern. For instance, operator+() returns
    Set<Pair<T> > by value and I think that it could matter sometimes. Or
    am I wrong and worry too much?

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
    Michal Nazarewicz, Nov 13, 2006
    #5
  6. "dasjotre" <> writes:
    > you basically want a template typedef?
    >
    > if so:
    >
    > template<class T>
    > struct Relation_typedef
    > {
    > typedef Set< Pair<T> > Relation;
    > };
    >
    > and use it as Relation_typedef<real type>::Relation
    > instead of Set<Pair<real type> >


    The way I see it, idea of aliases is to make names shorter and easier
    to read. ;)

    --
    Best regards, _ _
    .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
    ..o | Computer Science, Michal "mina86" Nazarewicz (o o)
    ooo +--<mina86*tlen.pl>---<jid:mina86*chrome.pl>--ooO--(_)--Ooo--
    Michal Nazarewicz, Nov 13, 2006
    #6
  7. Michal Nazarewicz

    Pete Becker Guest

    Michal Nazarewicz wrote:
    > "dasjotre" <> writes:
    >> you basically want a template typedef?
    >>
    >> if so:
    >>
    >> template<class T>
    >> struct Relation_typedef
    >> {
    >> typedef Set< Pair<T> > Relation;
    >> };
    >>
    >> and use it as Relation_typedef<real type>::Relation
    >> instead of Set<Pair<real type> >

    >
    > The way I see it, idea of aliases is to make names shorter and easier
    > to read. ;)
    >


    Well, sure. But not necessarily at this level of infrastructure. Once
    you have a name for type you're dealing with you write a typedef:

    typedef Relation_typedef<foo>::Relation foo_rel;

    --

    -- Pete
    Roundhouse Consulting, Ltd. -- www.versatilecoding.com
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." For more information about this book, see
    www.petebecker.com/tr1book.
    Pete Becker, Nov 13, 2006
    #7
  8. Michal Nazarewicz

    dasjotre Guest

    Michal Nazarewicz wrote:
    > "dasjotre" <> writes:
    > > you basically want a template typedef?
    > >
    > > if so:
    > >
    > > template<class T>
    > > struct Relation_typedef
    > > {
    > > typedef Set< Pair<T> > Relation;
    > > };
    > >
    > > and use it as Relation_typedef<real type>::Relation
    > > instead of Set<Pair<real type> >

    >
    > The way I see it, idea of aliases is to make names shorter and easier
    > to read. ;)
    >


    If you like to know why, go to comp.std.c++ and search
    for 'template typedefs'
    dasjotre, Nov 14, 2006
    #8
    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. Replies:
    0
    Views:
    284
  2. James Brown

    typedef aliasing

    James Brown, Oct 27, 2006, in forum: C Programming
    Replies:
    4
    Views:
    339
    James Brown
    Oct 27, 2006
  3. Adam Nielsen
    Replies:
    3
    Views:
    404
  4. oor
    Replies:
    0
    Views:
    1,343
  5. Replies:
    1
    Views:
    602
Loading...

Share This Page