template class won't compile after adding a destructor

Discussion in 'C++' started by Ethan, Apr 3, 2009.

  1. Ethan

    Ethan Guest

    //eylds.h

    #ifndef _EYL_DS_H_
    #define _EYL_DS_H_

    #include <cstdlib>
    #include <algorithm>
    #include "crtp.h"
    using eylcrtp::Comparable;

    enum direction_t {LEFT=0, RIGHT=1};

    template <class KeyType, class DataType> class AvlNode;
    template <class KeyType, class DataType> class AvlTree;
    typedef AvlNode<class KeyType, class DataType> NodeType;

    template <class KeyType, class DataType>
    class AvlNode : public Comparable< AvlNode<KeyType, DataType> > {
    public:

    enum {MAX_SUB = 2};
    AvlNode(KeyType k, DataType d) : _key(k), _data(d) { reset(); }

    /* ************************************** problem here
    **************************************
    ~AvlNode() {
    if (_subNodes
    ) delete _subNodes
    ;
    if (_subNodes
    ) delete _subNodes
    ;
    }

    **************************************************************************************************
    */


    bool operator<(const AvlNode& a) const { return _key < a._key; }
    KeyType key() { return _key; }
    DataType data() { return _data;}
    NodeType* child(direction_t d) { return _subNodes[d]; }
    short bal() { return _bal; }

    void reset() { _bal = 0; _subNodes
    = NULL; _subNodes
    =
    NULL;}

    friend class AvlTree<KeyType, DataType>;

    private:
    KeyType _key;
    DataType _data;
    short _bal;
    NodeType* _subNodes[MAX_SUB];
    };

    template <class KeyType, class DataType>
    class AvlTree {
    public:
    AvlTree() : _root(NULL) {}
    ~AvlTree() { if (_root) delete _root; }

    private:
    NodeType* _root;
    };

    #endif


    //main.cc
    #include <iostream>
    #include "eylds.h"
    using namespace std;

    int main() {
    int a = 5;
    int *p1 = &a;

    int b = 6;
    int *p2 = &b;
    AvlNode<int, int*> n1(a, p1);
    AvlNode<int, int*> n2(b, p2);

    cout << (n1 == n2) << endl;

    return 0;
    }

    these code compiled and run ok.


    But if I added the destructor, (the one commented out above), it
    wouldn't compile

    eylds.h: In instantiation of ‘AvlNode<KeyType, DataType>’:
    eylds.h:22: instantiated from ‘AvlNode<KeyType, DataType>::~AvlNode
    () [with KeyType = int, DataType = int*]’
    test_eylds.cc:11: instantiated from here
    eylds.h:38: error: ‘AvlNode<KeyType, DataType>::_key’ has incomplete
    type
    eylds.h:13: error: forward declaration of ‘struct KeyType’
    eylds.h:39: error: ‘AvlNode<KeyType, DataType>::_data’ has incomplete
    type
    eylds.h:13: error: forward declaration of ‘struct DataType’


    I couldn't figure out why, thank you in advance for your help!​
     
    Ethan, Apr 3, 2009
    #1
    1. Advertising

  2. Ethan

    Ethan Guest

    On Apr 2, 10:55 pm, Ethan <> wrote:
    > //eylds.h
    >
    > #ifndef _EYL_DS_H_
    > #define _EYL_DS_H_
    >
    > #include <cstdlib>
    > #include <algorithm>
    > #include "crtp.h"
    > using eylcrtp::Comparable;
    >
    > enum direction_t {LEFT=0, RIGHT=1};
    >
    > template <class KeyType, class DataType> class AvlNode;
    > template <class KeyType, class DataType> class AvlTree;
    > typedef AvlNode<class KeyType, class DataType> NodeType;
    >
    > template <class KeyType, class DataType>
    > class AvlNode : public Comparable< AvlNode<KeyType, DataType> > {
    > public:
    >
    >   enum {MAX_SUB = 2};
    >   AvlNode(KeyType k, DataType d) : _key(k), _data(d) { reset(); }
    >
    >   /*  ************************************** problem here
    > **************************************
    >   ~AvlNode() {
    >     if (_subNodes
    ) delete _subNodes
    ;
    >     if (_subNodes
    ) delete _subNodes
    ;
    >   }
    >
    > **************************************************************************************************
    > */
    >
    >   bool operator<(const AvlNode& a) const { return _key < a._key; }
    >   KeyType key() { return _key; }
    >   DataType data() { return _data;}
    >   NodeType* child(direction_t d) { return _subNodes[d]; }
    >   short bal() { return _bal; }
    >
    >   void reset() { _bal = 0; _subNodes
    = NULL; _subNodes
    =
    > NULL;}
    >
    >   friend class AvlTree<KeyType, DataType>;
    >
    > private:
    >   KeyType _key;
    >   DataType _data;
    >   short _bal;
    >   NodeType* _subNodes[MAX_SUB];
    >
    > };
    >
    > template <class KeyType, class DataType>
    > class AvlTree {
    > public:
    >   AvlTree() : _root(NULL) {}
    >   ~AvlTree() { if (_root) delete _root; }
    >
    > private:
    >   NodeType* _root;
    >
    > };
    >
    > #endif
    >
    > //main.cc
    > #include <iostream>
    > #include "eylds.h"
    > using namespace std;
    >
    > int main() {
    >   int a = 5;
    >   int *p1 = &a;
    >
    >   int b = 6;
    >   int *p2 = &b;
    >   AvlNode<int, int*> n1(a, p1);
    >   AvlNode<int, int*> n2(b, p2);
    >
    >   cout << (n1 == n2) << endl;
    >
    >   return 0;
    >
    > }
    >
    > these code compiled and run ok.
    >
    > But if I added the destructor, (the one commented out above), it
    > wouldn't compile
    >
    > eylds.h: In instantiation of ‘AvlNode<KeyType, DataType>’:
    > eylds.h:22:   instantiated from ‘AvlNode<KeyType, DataType>::~AvlNode
    > () [with KeyType = int, DataType = int*]’
    > test_eylds.cc:11:   instantiated from here
    > eylds.h:38: error: ‘AvlNode<KeyType, DataType>::_key’ has incomplete
    > type
    > eylds.h:13: error: forward declaration of ‘struct KeyType’
    > eylds.h:39: error: ‘AvlNode<KeyType, DataType>::_data’ has incomplete
    > type
    > eylds.h:13: error: forward declaration of ‘struct DataType’
    >
    > I couldn't figure out why, thank you in advance for your help!​



    seems the problem is typedef AvlNode<class KeyType, class DataType>
    NodeType;
    if I don't use this typedef, it works when I replaced all 'NodeType'
    by 'AvlNode<KeyType, DataType>'
    but I still don't understand why :(
     
    Ethan, Apr 3, 2009
    #2
    1. Advertising

  3. Ethan

    red floyd Guest

    On Apr 2, 8:55 pm, Ethan <> wrote:
    > //eylds.h
    >
    > #ifndef _EYL_DS_H_
    > #define _EYL_DS_H_
    >
    > #include <cstdlib>
    > #include <algorithm>
    > #include "crtp.h"
    > using eylcrtp::Comparable;
    >
    > enum direction_t {LEFT=0, RIGHT=1};
    >
    > template <class KeyType, class DataType> class AvlNode;
    > template <class KeyType, class DataType> class AvlTree;
    > typedef AvlNode<class KeyType, class DataType> NodeType;
    >


    Stop right there. template typedefs are not supported.
     
    red floyd, Apr 3, 2009
    #3
  4. Ethan

    litb Guest

    On 3 Apr., 06:08, Ethan <> wrote:
    > On Apr 2, 10:55 pm, Ethan <> wrote:
    >
    >
    >
    > > //eylds.h

    >
    > > #ifndef _EYL_DS_H_
    > > #define _EYL_DS_H_

    >
    > > #include <cstdlib>
    > > #include <algorithm>
    > > #include "crtp.h"
    > > using eylcrtp::Comparable;

    >
    > > enum direction_t {LEFT=0, RIGHT=1};

    >
    > > template <class KeyType, class DataType> class AvlNode;
    > > template <class KeyType, class DataType> class AvlTree;
    > > typedef AvlNode<class KeyType, class DataType> NodeType;

    >
    > > template <class KeyType, class DataType>
    > > class AvlNode : public Comparable< AvlNode<KeyType, DataType> > {
    > > public:

    >
    > >   enum {MAX_SUB = 2};
    > >   AvlNode(KeyType k, DataType d) : _key(k), _data(d) { reset(); }

    >
    > >   /*  ************************************** problem here
    > > **************************************
    > >   ~AvlNode() {
    > >     if (_subNodes
    ) delete _subNodes
    ;
    > >     if (_subNodes
    ) delete _subNodes
    ;
    > >   }​

    >
    > > **************************************************************************************************
    > > */

    >
    > >   bool operator<(const AvlNode& a) const { return _key < a._key; }
    > >   KeyType key() { return _key; }
    > >   DataType data() { return _data;}
    > >   NodeType* child(direction_t d) { return _subNodes[d]; }
    > >   short bal() { return _bal; }

    >
    > >   void reset() { _bal = 0; _subNodes
    = NULL; _subNodes
    =
    > > NULL;}​

    >
    > >   friend class AvlTree<KeyType, DataType>;

    >
    > > private:
    > >   KeyType _key;
    > >   DataType _data;
    > >   short _bal;
    > >   NodeType* _subNodes[MAX_SUB];

    >
    > > };

    >
    > > template <class KeyType, class DataType>
    > > class AvlTree {
    > > public:
    > >   AvlTree() : _root(NULL) {}
    > >   ~AvlTree() { if (_root) delete _root; }

    >
    > > private:
    > >   NodeType* _root;

    >
    > > };

    >
    > > #endif

    >
    > > //main.cc
    > > #include <iostream>
    > > #include "eylds.h"
    > > using namespace std;

    >
    > > int main() {
    > >   int a = 5;
    > >   int *p1 = &a;

    >
    > >   int b = 6;
    > >   int *p2 = &b;
    > >   AvlNode<int, int*> n1(a, p1);
    > >   AvlNode<int, int*> n2(b, p2);

    >
    > >   cout << (n1 == n2) << endl;

    >
    > >   return 0;

    >
    > > }

    >
    > > these code compiled and run ok.

    >
    > > But if I added the destructor, (the one commented out above), it
    > > wouldn't compile

    >
    > > eylds.h: In instantiation of ‘AvlNode<KeyType, DataType>’:
    > > eylds.h:22:   instantiated from ‘AvlNode<KeyType, DataType>::~AvlNode
    > > () [with KeyType = int, DataType = int*]’
    > > test_eylds.cc:11:   instantiated from here
    > > eylds.h:38: error: ‘AvlNode<KeyType, DataType>::_key’ has incomplete
    > > type
    > > eylds.h:13: error: forward declaration of ‘struct KeyType’
    > > eylds.h:39: error: ‘AvlNode<KeyType, DataType>::_data’ has incomplete
    > > type
    > > eylds.h:13: error: forward declaration of ‘struct DataType’

    >
    > > I couldn't figure out why, thank you in advance for your help!

    >
    > seems the problem is typedef AvlNode<class KeyType, class DataType>
    > NodeType;
    > if I don't use this typedef, it works when I replaced all 'NodeType'
    > by 'AvlNode<KeyType, DataType>'
    > but I still don't understand why :(


    "class X" is an elaborated type specifier. In a declaration, you
    basically have different specifiers. some specifiers are type
    qualifiers (const, volatile), some are simple type specifiers (int,
    unsigned, ...) and some are elaborated type specifiers (class X, union
    F) and you can of course just name a type previously declared "F"
    instead of "class F" if F is already known to be a class name.

    If you use that kind of elaborated type specifier, what happens is
    that the name is made known as a class name and the whole specifier
    names that class type then. If it wasn't known before, it will be a
    new, incomplete type. That's your case. Your stuff is just the same as
    saying

    class KeyType;
    class DataType;

    typedef AvlNode<KeyType, DataType> NodeType;

    They do *not* name template parameters. But they name new, incomplete
    types. You cannot typedef a template like that. Wait for the next C++
    Standard (which will take its own time to be implemented by compiler
    vendors) and you can do

    template<class KeyType, class DataType>
    using NodeType = AvlNode<KeyType, DataType>;

    Hope this helps.​
     
    litb, Apr 5, 2009
    #4
  5. Ethan

    James Kanze Guest

    On Apr 3, 5:55 am, Ethan <> wrote:
    > //eylds.h


    > #ifndef _EYL_DS_H_
    > #define _EYL_DS_H_


    > #include <cstdlib>
    > #include <algorithm>
    > #include "crtp.h"
    > using eylcrtp::Comparable;


    > enum direction_t {LEFT=0, RIGHT=1};


    > template <class KeyType, class DataType> class AvlNode;
    > template <class KeyType, class DataType> class AvlTree;
    > typedef AvlNode<class KeyType, class DataType> NodeType;


    What's this line supposed to mean? It doesn't correspond to any
    C++ syntax I know. (Curiously, g++ seems to accept it without
    an error message. Looks like a bug in g++ to me.)

    I couldn't try more, since I don't have "crtp.h", and I don't
    know what eylcrtp::Comparable is. (I deleted all but the three
    lines above for my quick test.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 5, 2009
    #5
  6. * James Kanze:
    > On Apr 3, 5:55 am, Ethan <> wrote:
    >> //eylds.h

    >
    >> #ifndef _EYL_DS_H_
    >> #define _EYL_DS_H_

    >
    >> #include <cstdlib>
    >> #include <algorithm>
    >> #include "crtp.h"
    >> using eylcrtp::Comparable;

    >
    >> enum direction_t {LEFT=0, RIGHT=1};

    >
    >> template <class KeyType, class DataType> class AvlNode;
    >> template <class KeyType, class DataType> class AvlTree;
    >> typedef AvlNode<class KeyType, class DataType> NodeType;

    >
    > What's this line supposed to mean? It doesn't correspond to any
    > C++ syntax I know. (Curiously, g++ seems to accept it without
    > an error message. Looks like a bug in g++ to me.)


    Seems OK technically. As noted earlier, else-thread, by "litb", it's just use of
    elaborated type identifiers. It's not a template typedef.

    So, being technically OK, that part compiles fine with e.g. Comeau.

    But some confusion that it would be a template typedef is probably the problem,
    as "litb" noted.


    Cheers & hth.,

    - Alf

    --
    Due to hosting requirements I need visits to <url: http://alfps.izfree.com/>.
    No ads, and there is some C++ stuff! :) Just going there is good. Linking
    to it is even better! Thanks in advance!
     
    Alf P. Steinbach, Apr 5, 2009
    #6
    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. christopher diggins
    Replies:
    16
    Views:
    761
    Pete Becker
    May 4, 2005
  2. frs
    Replies:
    20
    Views:
    762
    Alf P. Steinbach
    Sep 21, 2005
  3. iTooo
    Replies:
    4
    Views:
    520
    Peter_Julian
    Nov 5, 2005
  4. arun
    Replies:
    2
    Views:
    550
    benben
    Jun 13, 2006
  5. Skybuck Flying
    Replies:
    10
    Views:
    5,153
    Alf P. Steinbach /Usenet
    Jul 5, 2011
Loading...

Share This Page