1

I have an error with the following code, using the inner template class Node. the error is when declaring the root private field:

"member root declared as a template".

template <typename KeyType, typename ValueType>
class TreapBST : public AbstractBST<KeyType, ValueType>
{
public:
    .....

private:
   template <typename K, typename V>
   struct Node
   {
       ....
   };

    template <typename K, typename V>
    typename TreapBST<K, V>::Node<K, V>* root = nullptr;

};
Nissim Levy
  • 165
  • 10
  • And what should `template ... root` mean? How are you going to specify its template arguments? Or how should a compiler deduce them? – Evg Nov 22 '21 at 19:08
  • it should be a pointer to the root of the Treap (BST + Heap) – Nissim Levy Nov 22 '21 at 19:09
  • But what are `K` and `V` that a compiler should use? – Evg Nov 22 '21 at 19:11
  • 4
    You cannot have template fields or field templates. Luckily you don't need any in this case. You want `Node * root = nullptr;`. `struct Node` shouldn't be a template either. – n. m. could be an AI Nov 22 '21 at 19:11
  • 1
    I removed the duplicate here. There are other stuff than simply adding `template` at the right spot. – Guillaume Racicot Nov 22 '21 at 19:20
  • @n.1.8e9-where's-my-sharem. but it doesn't work without struct Node being a template – Nissim Levy Nov 22 '21 at 19:24
  • 5
    in what way does it not work? Node will be a template in the sense that it is a private class of a class template. When you write a class template you do not need to keep repeating `template ` unless you want that K and V to be *two different types* than the class parameters KeyType and ValueType – jwezorek Nov 22 '21 at 19:28
  • Ah i see, thank you very much. – Nissim Levy Nov 22 '21 at 19:34

1 Answers1

3

I think you have the basic idea right but are getting the syntax confused.

When you write a class template you do not need to keep repeating template <typename K, typename V> for each member unless you want that K and V to be two types that are different from class parameters KeyType and ValueType. If you just need KeyType and ValueType you don't need to redeclare members as templates.

For example the following will compile:

template <typename KeyType, typename ValueType>
class AbstractBST
{
    //...
};

template <typename KeyType, typename ValueType>
class TreapBST : public AbstractBST<KeyType, ValueType>
{
public:
    //...

private:

    struct Node
    {
        KeyType key;
        ValueType val;
        //...
    };

    Node* root = nullptr;

};

int main()
{
    TreapBST<std::string, int> treap;
    return 0;
};
jwezorek
  • 8,592
  • 1
  • 29
  • 46