0

I am working on an exercise to make sense of C++'s accessibility VS visibility.

The following code doesn't compile obviously, but this is what it ideally must be.

B inherits from A with template parameter Node, and Node is private to B.

template<typename T>
class A {...};


template<typename T>
class B: public A<B<T>::Node> {
private:
    struct Node{ int x=42;};
};

My tentative was:

template<typename T>
class A {...};


template<typename T>
class B: public A<B<T>::N> {
private:
    struct Node{ int x=42;};
public:
    typedef Node N;
};

I get Error: type/value mismatch at argument 1 in template parameter list for ‘template class A’ for both.

I am really lost with this, your help is appreciated.

1 Answer 1

1

The problem is that B<T>::Node cannot be used in that line since B<T> is not yet complete. Without a complete definition of B, the compiler cannot use the nested type.

The error will be clearer if you use:

template<typename T>
class B: public A<typename B<T>::Node> {
private:
    struct Node{ int x=42;};
};

With that, g++ produces a more easily understood error with the following code.

template<typename T>
class A {};    

template<typename T>
class B: public A<typename B<T>::Node> {
private:
    struct Node{ int x=42;};
};

int main()
{
   B<int> b;
}

Compiler error:

socc.cc: In instantiation of ‘class B<int>’:
socc.cc:13:11:   required from here
socc.cc:6:7: error: invalid use of incomplete type ‘class B<int>’
 class B: public A<typename B<T>::Node> {
       ^
socc.cc:6:7: note: declaration of ‘class B<int>’
socc.cc: In function ‘int main()’:
socc.cc:13:11: warning: unused variable ‘b’ [-Wunused-variable]
    B<int> b;
           ^

You commented

More concretely the problem is that A is a Tree and B an array-like container that saves in memory my defined Node using the Tree structure. So container needs to use internally a tree of nodes. I suppose this is more or less a common design for data structures, so how can the problem be resolved typically?

This calls for aggregation not inheritance.

template<typename T>
class A { ... };


template <typename T>
class B {
   private:
      struct Node{ int x=42;};
      A<Node> data;
};
1
  • Thanks for your reply, More concretely the problem is that A is a Tree and B an array-like container that saves in memory my defined Node using the Tree structure. So container needs to use internally a tree of nodes. I suppose this is more or less a common design for datastructures, so how can the problem be resolved typically ?
    – user10671686
    Commented Nov 29, 2018 at 1:20