Klaus Klaus - 1 year ago 32
C++ Question

accessing definitions from sub class in templated class

I have trouble to build a class which itself contains a subclass which self derives from class which needs template parameters from the top class. Sound horrible and it is indeed deep inside some MTP construction. But have a look on a simple example which I could shrink from the real code.

I leave the names as is in my original source. They are not important here.

template <typename ... T>
class ConstructAll: public T...
{
public:
using ConstructorParms = int;
using BASES_T = ConstructAll<T...>;
ConstructAll(int){}
};

template <typename T>
class WithTemplate
{
};

class WithoutTemplate
{
};


template <typename X>
class CircuitFromNetlist
{
private:
class SerialReader: public ConstructAll<
WithTemplate<X> // use this-> don't compile
//WithoutTemplate // but this works
>
{
public:
SerialReader( typename BASES_T::ConstructorParms p): BASES_T( p ) {}
};

public:
CircuitFromNetlist()
{
SerialReader ser{1};
}
};

int main()
{
CircuitFromNetlist<int> c;
}


If I use
WithTemplate<X>
it did not compile and runs into:

main.cpp:31:40: error: 'BASES_T' has not been declared
SerialReader( typename BASES_T::ConstructorParms p): BASES_T( p ) {}
^~~~~~~
main.cpp: In constructor 'CircuitFromNetlist::SerialReader::SerialReader(int)':
main.cpp:31:70: error: class 'CircuitFromNetlist::SerialReader' does not have any field named 'BASES_T'
SerialReader( typename BASES_T::ConstructorParms p): BASES_T( p ) {}

If I flip the code to use non templated class it seems to work.

Some idea to get the thing working?

Answer Source

What you're seeing here is actually correct behavior according to the C++11 standard:

In the definition of a class or class template, if a base class depends on a template-parameter, the base class scope is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member. -- [temp.dep] (emphasis mine)

When you inherit from ConstructAll<WithoutTemplate>, the base class does not depend on the template parameter X, but obviously inheriting from ConstructAll<WithTemplate<X>> the base class does depend on this template parameter.

You will have to explicitly refer to the type as typename ConstructAll<WithTemplate<X>>::BASES_T.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download