Calling base class function when base is a template

This is a discussion on Calling base class function when base is a template within the C++ Programming forums, part of the General Programming Boards category; Ran into an interesting issue last night when working on a few side projects. I have a base template class ...

Calling base class function when base is a template

Ran into an interesting issue last night when working on a few side projects. I have a base template class that has some virtual functions and I'm overriding one or more of them in the derived. One of them needs to call into the base class version of the function. Normally I would rename the function in the derived and then call the function in the base but in this case the name of the function for the derived fits perfectly into what it does.

Is there a way to call the base without forcing me to type out the entire template and it's types (the bold portion of my code)? Normally I typedef this but was not sure how to do it since the class derives from the base template and specified the types during derivation. Typedef'ing Foo<string,object> in a class that derives from Foo and sets the types to string and Object feels a bit odd to me but maybe it isn't really any different than what I normally do. I'm sure typedef'ing works but is there a better way to do this?

How portable would you like it to be? Which compilers are you targeting?

Code:

// GCC/SPARC/IBM but not MSVC (the ones I can test with)
Foo::AddRef(ID); // no template "arguments"

Code:

// GCC/MSVC but not SPARC/IBM (the ones I can test with)
typedef Foo<string,Object> Base;
Base::AddRef(ID); // using typedef

I only ask because fully specifying the name you wish to use is the only portable and reliable way to get what you want.

[Edit]
I realize you didn't ask, but I used to always do this by using a protected non-virtual method implementing the desired common behavior and providing a default implementation of the virtual method for forwarding behavior.
[/Edit]

I figured the typedef would work it just felt a bit odd b/c of the derivation. But in the end I guess it is no different than typedef'ing anything else.

I realize you didn't ask, but I used to always do this by using a protected non-virtual method implementing the desired common behavior and providing a default implementation of the virtual method for forwarding behavior.

That is another approach that I did not think of. Thanks for the tip. My question was pretty wide open so your suggestions, whatever they may be, are more than welcomed.

Okay. Then I'll also offer a bit more. That method has a major problem when it hits the real world and other programmers come out to play.

The common solution is a two stage approach where the public non-virtual interface method calls a private non-virtual implementation before calling a protected virtual method that provides the class specific behavior. This method has many of the same problems.

These days I use a combination of the above method with "mixin" classes and "RAII" to forcibly correct and catch most of the problems. The "mixin" classes have a few virtual methods and a few implemented methods to provide the "affix" calls. The target classes specific behavior need only create an instance of a nested class provided by the "mixin" for compliance.

*shrug*

The implementation can get remarkably convoluted (especially if you want portability), but the compiler and linker will complain a lot if a programmer comes by and forgets to overload the target function or "apply" all the inherited behavior.

That's ugly, iMalc. What you're doing, if T is a derived class, is indirectly forcing the base class to rely on knowledge of the derived class. That violates the Liskov substitution principle. Regardless of how you've achieved that, such things become difficult to maintain for anyone maintaining (or, worse, deriving from) that derived class.

Generally, I'd use the typedef approach. A derived class always knows what its base class is, so all you're quibbling over is syntax for referring to it. (I'd also std::string rather than relying on a using statement to resolve "string", but that's another story).

If and only if, in the base class, you know that all derived classes will need to reuse the supplied behaviour, one way follows.

I've done addRefOverrideableImplementation(ID Theid) as a pure virtual function to force the derived class to override it. However, if you want it to be optional for the derived class to do that, to provide an empty body and don't make the function pure.

If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

That's ugly, iMalc. What you're doing, if T is a derived class, is indirectly forcing the base class to rely on knowledge of the derived class. That violates the Liskov substitution principle. Regardless of how you've achieved that, such things become difficult to maintain for anyone maintaining (or, worse, deriving from) that derived class.

O_o

What a bunch of trash. The "Curiously Recurring Template Pattern" is extremely well known, used in hundreds of libraries, and even used in other languages.

Maintaining one implementation is always less difficult than maintaining multiple definitions.

Maintaining the derived class is a non-issue; you never need do anything more than publicly or privately inherit the implementation class if the implementation class is written correctly.

Much of well known "Boost" library could not exist without this pattern.

Any "mixin" or "co-implementation" mechanism is ultimately impossible without this pattern.

"LSP" only applies to "OOP". "CRTP" isn't "OOP". This is an entirely unrelated field that falls under the "Good Programming" umbrella.

If and only if, in the base class, you know that all derived classes will need to reuse the supplied behaviour, one way follows.

It is ugly purely from the point of view that any cast is ugly. However it is a common technique as noted, and if you missed my brief mention of the acronym then it's easy enough to not notice the use of this pattern.

I just threw it out there. It quite possibly doesn't suit, but it's hard to tell without more info.

AFAIK pure virtual functions are not allowed in template classes. I'm going to go with the typedef method since it appears to be the simpler and more straightforward approach. This isn't for production code anyways and is for a side game project I'm working on with a few people. There might be a few maintaining the code but it isn't to the degree that it would be if it were being done for a company of several hundred devs so I'm not too concerned with maintenance. Plus since it is a one-shot game project I doubt I will ever see the code again.

I just threw it out there. It quite possibly doesn't suit, but it's hard to tell without more info.

On that I agree. However, for the information available on the problem, I would suggest it is using a large implement to crack a small nut. It being a recurring pattern, does not justify using it without need. Unnecessarily doing such things tends to make things more difficult to understand, and therefore harder to maintain.

Originally Posted by Bubba

AFAIK pure virtual functions are not allowed in template classes.

That is not true. It is true that some coding guidelines discourage virtual functions (pure or not) in template classes.

If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.