Protected member is unknown for derived class

c++

Solution

You need

this->nod.find(k2);

or

_base_graph<K, void*, T>::nod.find ....;

The base and the derived classes are templates, and in your code `nod` is a non-dependent name, and so is looked up at the point of `graph`'s declaration. This is the first phase of the two-phase lookup. At this stage, it is impossible for the compiler (provided it follows the name lookup rules of the standard) to know what `nod` means, because it does not consider the base class until the second phase. So it is necessary to tell the compiler that `nod` should be looked up in the second phase. To do this, we explicitly tell it that `nod` is in a base class by using one of the forms above.

The reason for this behaviour is that at the point of the derived class' definition, it should not possible to know what `_base_graph<K, void*, T>::` contains, to allow for specializations of the template that add and even hide names. So the trick above makes sure that the names are looked up at the point of the derived class' instantiation, when all the information is available.

In summary, there are two issues in play here:

- `nod` is not a dependent name, so it would be looked up in the first phase.

- The base class template, which declared `nod`, is not available until the second phase, so the name cannot be resolved.

By using `this->nod` or `_base_graph<K, void*, T>::nod`, we are explicitly dealing with a dependent name, forcing the lookup to take place in the second phase.

See points 7 to 10 here.

Thanks to @DavidRodriguez-dribeas for clarifying some of the finer points of the two phase look-up.

Problem

I found an open source class library for Graphs. When I included it in my project it has many errors and I tried to fix them. But there is a compile error that I can not solve it. Base class: ``` template <typename K, typename W, typename T> class _base_graph { //... protected: std::map<K, T> nod; std::list<edge> edg; }; ``` Derived class: ``` template <typename K, typename T = void*> class graph : public _base_graph<K, void*, T> { //... public: void add_edge(const K& k1, const K& k2); }; ``` Method body: ``` template <typename K, typename T> void graph<K, T>::add_edge(const K& k1, const K& k2) { if (nod.find(k1) == nod.end() || nod.find(k2) == nod.end()) // <-- error!! throw std::string("add_edge: Node does not exist"); // ... } ``` But my gcc compiler show me an error: error: ‘nod’ was not declared in this scope You can find and test mycode in this online compiler.

Original source