inheritance, scope, and template constructors in c++

Go To StackoverFlow.com

0

I have a quick question. I am writing C++ code; I have two classes in the same file. One inherits from the other, and I am trying to use templates to make the classes more general.

Here is the file for the base class:

template<class E> // this is the class we will execute upon
class Exec{

protected: 

    typedef void (*Exe)(E*); // define a function pointer which acts on our template class.

    Exe* ThisFunc; // the instance of a pointer function to act on the object
    E* ThisObj;    // the object upon which our pointer function will act

public:

    Exec(Exe* func, E* toAct){ThisFunc = func; ThisObj=toAct;} 
    Exec(){;} // empty constructor

void Execute(){ThisFunc(ThisObj);} // here, we pass our object to the function

};

And here is the inherited class:

template<class E> // this is the class we will execute upon
class CondExec : protected Exec<E>{ // need the template!

protected:

    typedef bool (*Cond)(E*); // a function returning a bool, taking a template class
    Cond* ThisCondition;

public:

CondExec(Exe* func, E* toAct,Cond* condition): Exec<E>(func,toAct){ThisCondition=condition;}

void ExecuteConditionally(){
    if (ThisCondition(ThisObj)){
        Execute();
        }
    }
};

However, when I try this, I get the following errors:

executables.cpp:35: error: expected `)' before ‘*’ token
executables.cpp: In member function ‘void CondExec<E>::ExecuteConditionally()’:
executables.cpp:37: error: ‘ThisObj’ was not declared in this scope
executables.cpp:37: error: there are no arguments to ‘Execute’ that depend on a template             parameter, so a declaration of ‘Execute’ must be available

It seems that the Exec (ie: the base) class isn't getting properly declared; if I include the typedef and the instance variables from the base class in the inherited class, I don't get these errors. However, if I include everything from the base class, then its pointless to use inheritance!

I've tried doing a "declaration" of the base class, as some have recommended (ie: class Base;), but that doesn't seem to help.

I've been doing some google-fu on this for some hours; if anyone has any ideas, that'd be super!

2012-04-04 18:10
by heisenBug
typename CondExec::Exe, this->ThisObj and this->Execute() - Luc Danton 2012-04-04 18:15


3

You need to say typename Exec<E>::Exe. Because the baseclass is dependent. Same for Execute, you need to qualify the call with the baseclass name in front: Exec<E>::Execute();.

Otherwise those unqualified names ignore the dependent base class.

2012-04-04 18:13
by Johannes Schaub - litb
So you are saying after each instance variable I use in the baseclass, I need to qualify the class with the baseclass name? I guess my confusion is where it is appropriate to qualify methods or instance variable - heisenBug 2012-04-04 18:24
@user1313502: If the type/variable/function depends on the template, it needs either Exec<E>:: (for types and functions) or this-> (for member variables) - Mooing Duck 2012-04-04 18:29
@user1313502 yes that is what I am saying. Dependent base classes are ignored when looking for unqualified names. That's to add more safety, so that when a dependent base class would declare a member of that name, the meaning of the name does not suddenly change from being a global declaration to being a base class member declaration. If you want it to be a base class member, you need to prefix the name with BaseClass:: or this-> as appropriate - Johannes Schaub - litb 2012-04-04 20:22
Ads