I wasn't sure about a proper title. It does seem confusing. Sorry for that.
I am not a programmer. So please, bear with me. I am surely using some terminology wrongly.
Here's what I want to achieve:
Have a base class A_base with some nested class (sub-class?) defined in it (B_base). A_base will have all kinds of common functions that do not require specialization. The nested class is providing some interface for communication with another application (there are callbacks in it, which I define according to my needs).
class A_base
{
public:
void a_function()
{
std::cout << "This is a base a_function\n" ;
}
void a_b_function();
class B_base
{
public:
void b_function()
{
std::cout << "This is a base b_function\n" ;
}
void b_a_function();
virtual void b_c_function1(){return;};
virtual void b_c_function2(){return;};
B_base(const std::string& name_in, A_base* ptr_A_in):
name(name_in), ptr_A(ptr_A_in)
{}
protected:
const std::string name;
A_base* ptr_A;
};
B_base* b_object;
A_base(const std::string& name_in):
b_object(new B_base(name_in, this)), name(name_in)
{}
protected:
const std::string name;
};
void A_base::a_b_function()
{
b_object->b_function();
}
void A_base::B_base::b_a_function()
{
ptr_A->a_function();
}
Derive a templated class out of A_base (A_derived) with some additional specialized functionality and another nested class in it (C_class, which is also templated). I chose this to optimize the latency of my program. It doesn't have to be always lightning fast, but there's one particular path in the logic that must be as fast as possible. Therefore, I am trying to eliminate unnecessary branching by using templates.
enum Side{BB=0,SS=1};
template<bool B>
class A_derived : public A_base
{
public:
void a_function()
{
std::cout << "This is a derived a_function\n" ;
}
template<Side S>
class C_class
{
public:
void c_function();
C_class(const std::string& name_in, A_derived* ptr_A_in):
name(name_in), ptr_A(ptr_A_in)
{}
protected:
const std::string name;
A_derived* ptr_A;
};
C_class<Side::BB> c_object_bb;
C_class<Side::SS> c_object_ss;
A_derived(const std::string& name_in):
A_base(name_in), c_object_bb(name_in, this), c_object_ss(name_in, this)
{}
};
Here I am defining the specialized functions (the ones that are supposed to be fast):
template<> template<>
void A_derived<false>::C_class<Side::BB>::c_function()
{
std::cout << "This is a false-BB c_function\n" ;
}
template<> template<>
void A_derived<false>::C_class<Side::SS>::c_function()
{
std::cout << "This is a false-SS c_function\n" ;
}
template<> template<>
void A_derived<true>::C_class<Side::BB>::c_function()
{
std::cout << "This is a true-BB c_function\n" ;
}
template<> template<>
void A_derived<true>::C_class<Side::SS>::c_function()
{
std::cout << "This is a true-SS c_function\n" ;
}
And on top of that there's a need to be able to call some of the specialized functions out of a method of a nested class B_base. The specialized functions belong to a C_class. Hence, B_base knows nothing about it. But I am trying to circumvent this by casting the A_base pointer into A_derived pointer. I know for sure what kind of A_derived will be used in each case.
The problem is, the C_class function has to be called depending on the version of A_derived that is used. But B_base itself is not a templated class. So, clearly the following is not working the way I want it to work:
void A_derived<false>::B_base::b_c_function1()
{
static_cast<A_derived<false>*>(ptr_A)->c_object_bb.c_function();
}
void A_derived<false>::B_base::b_c_function2()
{
static_cast<A_derived<false>*>(ptr_A)->c_object_ss.c_function();
}
void A_derived<true>::B_base::b_c_function1()
{
static_cast<A_derived<true>*>(ptr_A)->c_object_bb.c_function();
}
void A_derived<true>::B_base::b_c_function2()
{
static_cast<A_derived<true>*>(ptr_A)->c_object_ss.c_function();
}
It just complains about redefining functions. And if I add template<> syntaxis it complains that there is not template out there. And it's kinda true. Can't blame the compiler for this.
Can you please suggest me a reasonable solution? How can I call a templated function of a nested class of a derived class from a method of a nested class of a base class?
Thank you.
Added: So, one person suggested in the comments I should use virtual functions instead. After some thinking I decided to clarify. B_base has its functions as virtual, actually. And this is not my code. I just have to deal with it. The reason virtual functions are of little help is that I cannot simply derive my A_base off B_base (due to some reasons). And for the most of B_base's functions I am fine with some common definitions. However, there are 10% of B_base's functions that I want to be specialized, depending on A_derived that is being instantiated.
My back up solution is to not use B_base at all but rather have some derived B_derived that'd be fully defined inside my A_derived. Unfortunately that would mean writing an infinite amount of useless code. Because most of B_base functions do not depend on type of A_derived.
I have a function User::func()(callback) that would be called by a template class (Library<T>).
In the first iteration of development, everyone know that func() serves only for that single purpose.
A few months later, most members forget what func() is for.
After some heavy refactoring, the func() is sometimes deleted by some coders.
At first, I didn't think this is a problem at all.
However, after I re-encountered this pattern several times, I think I need some counter-measure.
Question
How to document it elegantly? (cute && concise && no additional CPU cost)
Example
Here is a simplified code:-
(The real world problem is scattering around 10+ library-files & 20+ user files & 40+ functions.)
Library.h
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
node->func(); //#1
}
};
User.h
class User{
public: void func(){/** some code*/} //#1
//... a lot of other functions ...
// some of them are also callback of other libraries
};
main.cpp
int main(){
Library<User> li; .... ; li.utility();
}
My poor solutions
1. Comment / doc
As the first workaround, I tend to add a comment like this:-
class User{
/** This function is for "Library" callback */
public: void func(){/** some code*/}
};
But it gets dirty pretty fast - I have to add it to every "func" in every class.
2. Rename the "func()"
In real case, I tend to prefix function name like this:-
class User{
public: void LIBRARY_func(){/** some code*/}
};
It is very noticeable, but the function name is now very longer.
(especially when Library-class has longer class name)
3. Virtual class with "func()=0"
I am considering to create an abstract class as interface for the callback.
class LibraryCallback{
public: virtual void func()=0;
};
class User : public LibraryCallback{
public: virtual void func(){/** some code*/}
};
It provides feeling that func() is for something-quite-external. :)
However, I have to sacrifice virtual-calling cost (v-table).
In performance-critical cases, I can't afford it.
4. Static function
(idea from Daniel Jour in comment, thank!)
Almost 1 month later, here is how I use :-
Library.h
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
T::func(node); //#1
}
};
User.h
class User{
public: static void func(Callback*){/** some code*/}
};
main.cpp
int main(){
Library<User> li;
}
It is probably cleaner, but still lack self-document.
func is not a feature of User. It is a feature of the User-Library<T> coupling.
Placing it in User if it doesn't have clear semantics outside of Library<T> use is a bad idea. If it does have clear semantics, it should say what it does, and deleting it should be an obviously bad idea.
Placing it in Library<T> cannot work, because its behavior is a function of the T in Library<T>.
The answer is to place it in neither spot.
template<class T> struct tag_t{ using type=T; constexpr tag_t(){} };
template<class T> constexpr tag_t<T> tag{};
Now in Library.h:
struct ForLibrary;
template<class T> class Library{
public: T* node=nullptr;
public: void utility(){
func( tag<ForLibrary>, node ); // #1
}
};
in User.h:
struct ForLibrary;
class User{
/** This function is for "Library" callback */
public:
friend void func( tag_t<ForLibrary>, User* self ) {
// code
}
};
or just put this into the same namespace as User, or the same namespace as ForLibrary:
friend func( tag_t<ForLibrary>, User* self );
Before deleting func, you'll track down ForLibrary.
It is no longer part of the "public interface" of User, so doesn't clutter it up. It is either a friend (a helper), or a free function in the same namespace of either User or Library.
You can implement it where you need a Library<User> instead of in User.h or Library.h, especially if it just uses public interfaces of User.
The techniques used here are "tag dispatching", "argument dependent lookup", "friend functions" and preferring free functions over methods.
From the user side, I would use crtp to create a callback interface, and force Users to use it. For example:
template <typename T>
struct ICallbacks
{
void foo()
{
static_cast<T*>(this)->foo();
}
};
Users should inherit from this interface and implement foo() callback
struct User : public ICallbacks<User>
{
void foo() {std::cout << "User call back" << std::endl;}
};
The nice thing about it is that if Library is using ICallback interface and User forget to implement foo() you will get a nice compiler error message.
Note that there is no virtual function, so no performance penalty here.
From the library side, I would only call those callbacks via its interfaces (in this case ICallback). Following OP in using pointers, I would do something like this:
template <typename T>
struct Library
{
ICallbacks<T> *node = 0;
void utility()
{
assert(node != nullptr);
node->foo();
}
};
Note that things get auto documented in this way. It is very explicit that you are using a callback interface, and node is the object who has those functions.
Bellow a complete working example:
#include <iostream>
#include <cassert>
template <typename T>
struct ICallbacks
{
void foo()
{
static_cast<T*>(this)->foo();
}
};
struct User : public ICallbacks<User>
{
void foo() {std::cout << "User call back" << std::endl;}
};
template <typename T>
struct Library
{
ICallbacks<T> *node = 0;
void utility()
{
assert(node != nullptr);
node->foo();
}
};
int main()
{
User user;
Library<User> l;
l.node = &user;
l.utility();
}
Test.h
#ifndef TEST_H
#define TEST_H
// User Class Prototype Declarations
class User;
// Templated Wrapper Class To Contain Callback Functions
// User Will Inherit From This Using Their Own Class As This
// Class's Template Parameter
template <class T>
class Wrapper {
public:
// Function Template For Callback Methods.
template<class U>
auto Callback(...) {};
};
// Templated Library Class Defaulted To User With The Utility Function
// That Provides The Invoking Of The Call Back Method
template<class T = User>
class Library {
public:
T* node = nullptr;
void utility() {
T::Callback(node);
}
};
// User Class Inherited From Wrapper Class Using Itself As Wrapper's Template Parameter.
// Call Back Method In User Is A Static Method And Takes A class Wrapper* Declaration As
// Its Parameter
class User : public Wrapper<User> {
public:
static void Callback( class Wrapper* ) { std::cout << "Callback was called.\n"; }
};
#endif // TEST_H
main.cpp
#include "Test.h"
int main() {
Library<User> l;
l.utility();
return 0;
}
Output
Callback was called.
I was able to compile, build and run this without error in VS2017 CE on Windows 7 - 64bit Intel Core 2 Quad Extreme.
Any Thoughts?
I would recommend to name the wrapper class appropriately, then for each specific call back function that has a unique purpose name them accordingly within the wrapper class.
Edit
After playing around with this "template magic" well there is no such thing...
I had commented out the function template in the Wrapper class and found that it is not needed. Then I commented out the class Wrapper* that is the argument list for the Callback() in User. This gave me a compiler error that stated that User::Callback() does not take 0 arguments. So I looked back at Wrapper since User inherits from it. Well at this point Wrapper is an empty class template.
This lead me to look at Library. Library has a pointer to User as a public member and a utility() function that invokes User's static Callback method. It is here that the invoking method is taking a pointer to a User object as its parameter. So it lead me to try this:
class User; // Prototype
class A{}; // Empty Class
template<class T = User>
class Library {
public:
T* node = nullptr;
void utility() {
T::Callback(node);
}
};
class User : public A {
public:
static void Callback( A* ) { std::cout << "Callback was called.\n"; }
};
And this compiles and builds correctly as the simplified version. However; when I thought about it; the template version is better because it is deduced at compile time and not run time. So when we go back to using templates javaLover had asked me what class Wrapper* means or is within the argument list for the Callback method within the User class.
I'll try to explain this as clearly as I can but first the wrapper Class is just an empty template shell that User will inherit from and it does nothing but act as a base class and it now looks like this:
template<class T>
class Wrapper { // Could Be Changed To A More Suitable Name Such As Shell or BaseShell
};
When we look at the User class:
class User : public Wrapper<User> {
public:
static void Callback( class Wrapper* ) { // print statement }
};
We see that User is a non-template class that inherits from a template class but uses itself as the template's argument. It contains a public static method
and this method doesn't return any thing but it does take a single parameter; this is also evident in the Library class that has its template parameter as a User class. When the Library's utility() method invokes User's Callback() method the parameter that the Library is expecting is a pointer to a User object. So when we go back to the User class instead of declaring it as a User* pointer directly in its declaration I'm using the empty class template that it inherits from. However if you try to do this:
class User : public Wrapper<User> {
public:
static void Callback( Wrapper* ) { // print statement }
};
You should get a message that Wrapper* is missing it's argument list. We could just do Wrapper<User>* here but that is redundant since we already see that User is inheriting from Wrapper that takes itself. So we can fix this and make it cleaner just by prefixing the Wrapper* with the class keyword since it is a class template. Hence the template magic... well there is no magic here... just compiler intrinsic and optimizations.
While I know that I don't answer your specific question (how to document the not-to-be-deleted function) I would solve your problem (keeping the seemingly unused callback function in the code base) by instantiating Library<User> and calling the utility() function in a unit test (or maybe it should rather be called an API test...). This solution would probably scale to your real world example too, as long as you don't have to check each possible combination of library classes and callback functions.
If you are lucky enough to work in an organization where successful unit tests and code review are required before changes go into the code base this would require a change to the unit tests before anyone could remove the User::func() function and such a change would probably catch the attention of a reviewer.
Then again, you know your environment and I don't, and I'm aware that this solution doesn't fit all situations.
Here is a solution using a Traits class:
// Library.h:
template<class T> struct LibraryTraits; // must be implemented for every User-class
template<class T> class Library {
public:
T* node=nullptr;
void utility() {
LibraryTraits<T>::func(node);
}
};
// User.h:
class User { };
// must only be implemented if User is to be used by Library (and can be implemented somewhere else)
template<> struct LibraryTraits<User> {
static void func(User* node) { std::cout << "LibraryTraits<User>::func(" << node << ")\n"; }
};
// main.cpp:
int main() {
Library<User> li; li.utility();
}
Advantages:
It is obvious by the naming that LibraryTraits<User> is only required for interfacing User by Library (and can be removed, once either Library or User gets removed.
LibraryTraits can be specialized independent of Library and User
Disadvantages:
No easy access to private members of User (making LibraryTraits a friend of User would remove the independence).
If the same func is needed for different Library classes multiple Trait classes need to be implemented (could be solved by default implementations inheriting from other Trait classes).
This heavily reminds an old good Policy-Based Design, except in your case you do not inherit the Library class from the User class.
Good names are the best friends of any API. Combine this and the well-known patter of Policy-Based Design (well-known is very important because the class names with the word Policy in it will immediately ring the bell in many readers of the code) and, I assume, you get a well self-documenting code.
Inheritance won't give you any performance overhead, but will give you an ability to have the Callback as a protected method, that will give some hint that it is supposed to be inherited and be used somewhere.
Have clearly standing-out and consistent naming among multiple User-like classes (e.g. SomePolicyOfSomething in the manner of aforementioned Policy-Based Design), as well as, the template arguments for the Library (e.g SomePolicy, or I would call it TSomePolicy).
Having using declaration of the Callback in the Library class might give much clearer and earlier errors (e.g. from IDE, or modern clang, visial studio syntax parsers for IDE).
Another arguable option might be a static_assert if you have C++>=11. But in this case it must be used in every User-like class ((.
Not a direct answer to your question on how to document it, but something to consider:
If your Library template requires an implementation of someFunction() for each class to be used in it, i'd recommend adding it as a template argument.
#include <functional>
template<class Type, std::function<void(Type*)> callback>
class Library {
// Some Stuff...
Type* node = nullptr;
public:
void utility() {
callback(this->node);
}
};
Might make it even more explicit, so that other devs know it's needed.
abstract class is the best way to enforce the function not to be deleted. So i recommend implementing the base class with pure virtual function, so that derived has to define the function.
OR second solution would be to have function pointers so that performance will be saved by avoiding extra overhead of V-table creation and calling.
If it is not obvious that func() is needed in User, then I'd argue you're violating the single responsibility principle. Instead create an adapter class of which User as a member.
class UserCallback {
public:
void func();
private:
User m_user;
}
That way the existance of UserCallback documents that func() is an external call back, and separates out Library's need of a callback from the actual responsibilities of User.
I've two functions
MultiplyVerison1(T x, T y); // in class A
MultiplyVersion1(T x, T y); // in class B
Above functions are in separate non-template classes.
Now, as part of refactoring I'm trying to create a base class of A and B and creating a pure virtual MultiplyVersion1 but a templte function cannot be marked virtual.
So, how can we achieve the same with template functions?
You can't. There's no way to call a function template in a derived class through a pointer-to-base, that's what "function templates cannot be virtual" means.
You can think of this as being because it's the call that triggers the instantiation of the function template with a particular type T -- if you call it with int, but the dynamic type of the object you're calling it on isn't known until runtime (whether it's A or B or something else), then there's no way for the compiler to know that it needs to instantiate A::MultiplyVersion1<int> or B::MultiplyVersion1<int> or something else. Actually there's more to it than that, but I think that's enough.
You can bodge around particular cases, but you won't get the full effect of a virtual function. Something like:
struct Base {
template <typename T>
void MultiplyVersion1(const T &x, const T &y) {
A *athis = dynamic_cast<A*>(this);
if (athis) {
athis->MultiplyVersion1(x,y);
} else {
B *bthis = dynamic_cast<B*>(this);
if (bthis) {
bthis->MultiplyVersion1(x,y);
} else {
throw std::logic_error();
}
}
}
virtual ~Base() {}
};
Now when you call MultiplyVersion1<int> via a pointer-to-base, both A::MultiplyVersion1<int> and B::MutiplyVersion1<int> are instantiated. But of course you can't easily add new derived classes, which is a serious restriction.
You could also re-consider whether you really need dynamic polymorphism at all, but that depends entirely on how you're planning to use that base class. You seem to have done OK without it so far.
If all you want from the base class is code re-use for some other functions, then you don't need dynamic polymorphism. Leave MultiplyVersion1 out of the base class entirely (and maybe don't inherit publicly from the Base, instead inherit privately and bring in the functions you want to re-use with using statements). If the functions you want to define for re-use call MultiplyVersion1, then consider simulated dynamic binding via CRTP:
#include <iostream>
template <typename Derived>
struct Base {
template <typename T>
void MultiplyVersion2(const T &x, const T &y) {
static_cast<Derived&>(*this).MultiplyVersion1(x + 1, y + 1);
}
};
struct A : private Base<A> {
friend class Base;
template <typename T> void MultiplyVersion1(T x, T y) {
std::cout << x*y << "\n";
}
using Base::MultiplyVersion2;
};
struct B : private Base<B> {
friend class Base;
template <typename T> void MultiplyVersion1(T x, T y) {
std::cout << x << " * " << y << " = " << x*y << "\n";
}
using Base::MultiplyVersion2;
};
int main() {
A a;
a.MultiplyVersion2(1,2);
B b;
b.MultiplyVersion2(1,2);
}
I'm not exactly sure how to word this in English, but I want to do something like this:
template <class T>
class derived: public T
{ blah };
Where basically, I have a template class, but I'm deriving a new class from the class that is specified in the template? I.e. so I wouldn't necessarily know the class at compile time.
Is this even possible? If so, What are the semantics for this?
For example, say I'm trying to write a "parent" class. For the purposes of this example, let's say it's a tree parent. The tree parent, is a tree itself (so it inherits from tree), but also has a vector of references to child trees.However, the parent class itself doesn't have to be a tree; it could be any class, such that I could write something like:
Parent<tree> treeParent;
Parent<shrub> shrubParent;
Yes. That is possible. Try doing that.
I wouldn't necessarily know the class at compile time.
I think, you mean "I wouldn't necessarily know the class at the time of defining the class template."
By the time you compile, you've already defined the class template, and used it in your code, passing template argument to it, which means you know the class (i.e template argument) at compile time. If you don't know the class to be used as base, then you cannot even compile the code.
This is indeed possible and commonly used for policy based design:
Like in this incredibly contrived example:
template<typename OutputPolicy>
struct Writer : public OutputPolicy {
using OutputPolicy::print;
void write(const std::string&) {
//do some formatting etc.
print(string);
}
};
class StdoutPolicy {
public:
set_linebreaks(const std::string&);
protected:
void print(const std::string&);
};
The public method in the policy will be accessible through Writer. That way a policy can decorate the class it is used in with additional methods.
Yes this is possible. The semantic for this is no different from the semantic for any other use of a template parameter in the class template. You can have a member of type T, a function parameter of type T, and you can have T as a base class too. It's not special.
Like this:
#include <iostream>
using namespace std;
template<typename T>class classTemplateBase
{
public:
T value;
classTemplateBase(T i)
{
this->value = i;
}
void test()
{
cout << value << endl;
}
};
class classTemplateChild : public classTemplateBase<char>
{
public:
classTemplateChild( ): classTemplateBase<char>( 0 ) // default char is NUL
{
;
}
classTemplateChild(char c): classTemplateBase<char>( c )
{
;
}
void test2()
{
test();
}
};
int main()
{
classTemplateBase <int> a( 42 );
classTemplateChild b( 'A' );
a.test(); // should print "42"
b.test(); // should print "A"
b.test2(); // should print "A"
return 0;
}
This is possible an it is also very common and has gotten it's own name: the Curiously recurring template pattern. See the Wikipeida entry on Curiously recurring template pattern.
Is it possible in C++ to have a member function that is both static and virtual? Apparently, there isn't a straightforward way to do it (static virtual member(); is a compile error), but is there at least a way to achieve the same effect?
I.E:
struct Object
{
struct TypeInformation;
static virtual const TypeInformation &GetTypeInformation() const;
};
struct SomeObject : public Object
{
static virtual const TypeInformation &GetTypeInformation() const;
};
It makes sense to use GetTypeInformation() both on an instance (object->GetTypeInformation()) and on a class (SomeObject::GetTypeInformation()), which can be useful for comparisons and vital for templates.
The only ways I can think of involves writing two functions / a function and a constant, per class, or use macros.
Any other solutions?
No, there's no way to do it, since what would happen when you called Object::GetTypeInformation()? It can't know which derived class version to call since there's no object associated with it.
You'll have to make it a non-static virtual function to work properly; if you also want to be able to call a specific derived class's version non-virtually without an object instance, you'll have to provide a second redunduant static non-virtual version as well.
Many say it is not possible, I would go one step further and say it is not meaningfull.
A static member is something that does not relate to any instance, only to the class.
A virtual member is something that does not relate directly to any class, only to an instance.
So a static virtual member would be something that does not relate to any instance or any class.
I ran into this problem the other day: I had some classes full of static methods but I wanted to use inheritance and virtual methods and reduce code repetition. My solution was:
Instead of using static methods, use a singleton with virtual methods.
In other words, each class should contain a static method that you call to get a pointer to a single, shared instance of the class. You can make the true constructors private or protected so that outside code can't misuse it by creating additional instances.
In practice, using a singleton is a lot like using static methods except that you can take advantage of inheritance and virtual methods.
While Alsk has already given a pretty detailed answer, I'd like to add an alternative, since I think his enhanced implementation is overcomplicated.
We start with an abstract base class, that provides the interface for all the object types:
class Object
{
public:
virtual char* GetClassName() = 0;
};
Now we need an actual implementation. But to avoid having to write both the static and the virtual methods, we will have our actual object classes inherit the virtual methods. This does obviously only work, if the base class knows how to access the static member function. So we need to use a template and pass the actual objects class name to it:
template<class ObjectType>
class ObjectImpl : public Object
{
public:
virtual char* GetClassName()
{
return ObjectType::GetClassNameStatic();
}
};
Finally we need to implement our real object(s). Here we only need to implement the static member function, the virtual member functions will be inherited from the ObjectImpl template class, instantiated with the name of the derived class, so it will access it's static members.
class MyObject : public ObjectImpl<MyObject>
{
public:
static char* GetClassNameStatic()
{
return "MyObject";
}
};
class YourObject : public ObjectImpl<YourObject>
{
public:
static char* GetClassNameStatic()
{
return "YourObject";
}
};
Let's add some code to test:
char* GetObjectClassName(Object* object)
{
return object->GetClassName();
}
int main()
{
MyObject myObject;
YourObject yourObject;
printf("%s\n", MyObject::GetClassNameStatic());
printf("%s\n", myObject.GetClassName());
printf("%s\n", GetObjectClassName(&myObject));
printf("%s\n", YourObject::GetClassNameStatic());
printf("%s\n", yourObject.GetClassName());
printf("%s\n", GetObjectClassName(&yourObject));
return 0;
}
Addendum (Jan 12th 2019):
Instead of using the GetClassNameStatic() function, you can also define the the class name as a static member, even "inline", which IIRC works since C++11 (don't get scared by all the modifiers :)):
class MyObject : public ObjectImpl<MyObject>
{
public:
// Access this from the template class as `ObjectType::s_ClassName`
static inline const char* const s_ClassName = "MyObject";
// ...
};
It is possible!
But what exactly is possible, let's narrow down. People often want some kind of "static virtual function" because of duplication of code needed for being able to call the same function through static call "SomeDerivedClass::myfunction()" and polymorphic call "base_class_pointer->myfunction()". "Legal" method for allowing such functionality is duplication of function definitions:
class Object
{
public:
static string getTypeInformationStatic() { return "base class";}
virtual string getTypeInformation() { return getTypeInformationStatic(); }
};
class Foo: public Object
{
public:
static string getTypeInformationStatic() { return "derived class";}
virtual string getTypeInformation() { return getTypeInformationStatic(); }
};
What if base class has a great number of static functions and derived class has to override every of them and one forgot to provide a duplicating definition for virtual function. Right, we'll get some strange error during runtime which is hard to track down. Cause duplication of code is a bad thing. The following tries to resolve this problem (and I want to tell beforehand that it is completely type-safe and doesn't contain any black magic like typeid's or dynamic_cast's :)
So, we want to provide only one definition of getTypeInformation() per derived class and it is obvious that it has to be a definition of static function because it is not possible to call "SomeDerivedClass::getTypeInformation()" if getTypeInformation() is virtual. How can we call static function of derived class through pointer to base class? It is not possible with vtable because vtable stores pointers only to virtual functions and since we decided not to use virtual functions, we cannot modify vtable for our benefit. Then, to be able to access static function for derived class through pointer to base class we have to store somehow the type of an object within its base class. One approach is to make base class templatized using "curiously recurring template pattern" but it is not appropriate here and we'll use a technique called "type erasure":
class TypeKeeper
{
public:
virtual string getTypeInformation() = 0;
};
template<class T>
class TypeKeeperImpl: public TypeKeeper
{
public:
virtual string getTypeInformation() { return T::getTypeInformationStatic(); }
};
Now we can store the type of an object within base class "Object" with a variable "keeper":
class Object
{
public:
Object(){}
boost::scoped_ptr<TypeKeeper> keeper;
//not virtual
string getTypeInformation() const
{ return keeper? keeper->getTypeInformation(): string("base class"); }
};
In a derived class keeper must be initialized during construction:
class Foo: public Object
{
public:
Foo() { keeper.reset(new TypeKeeperImpl<Foo>()); }
//note the name of the function
static string getTypeInformationStatic()
{ return "class for proving static virtual functions concept"; }
};
Let's add syntactic sugar:
template<class T>
void override_static_functions(T* t)
{ t->keeper.reset(new TypeKeeperImpl<T>()); }
#define OVERRIDE_STATIC_FUNCTIONS override_static_functions(this)
Now declarations of descendants look like:
class Foo: public Object
{
public:
Foo() { OVERRIDE_STATIC_FUNCTIONS; }
static string getTypeInformationStatic()
{ return "class for proving static virtual functions concept"; }
};
class Bar: public Foo
{
public:
Bar() { OVERRIDE_STATIC_FUNCTIONS; }
static string getTypeInformationStatic()
{ return "another class for the same reason"; }
};
usage:
Object* obj = new Foo();
cout << obj->getTypeInformation() << endl; //calls Foo::getTypeInformationStatic()
obj = new Bar();
cout << obj->getTypeInformation() << endl; //calls Bar::getTypeInformationStatic()
Foo* foo = new Bar();
cout << foo->getTypeInformation() << endl; //calls Bar::getTypeInformationStatic()
Foo::getTypeInformation(); //compile-time error
Foo::getTypeInformationStatic(); //calls Foo::getTypeInformationStatic()
Bar::getTypeInformationStatic(); //calls Bar::getTypeInformationStatic()
Advantages:
less duplication of code (but we
have to call
OVERRIDE_STATIC_FUNCTIONS in every
constructor)
Disadvantages:
OVERRIDE_STATIC_FUNCTIONS in every
constructor
memory and performance
overhead
increased complexity
Open issues:
1) there are different names for static and virtual functions
how to solve ambiguity here?
class Foo
{
public:
static void f(bool f=true) { cout << "static";}
virtual void f() { cout << "virtual";}
};
//somewhere
Foo::f(); //calls static f(), no ambiguity
ptr_to_foo->f(); //ambiguity
2) how to implicitly call OVERRIDE_STATIC_FUNCTIONS inside every constructor?
It is possible. Make two functions: static and virtual
struct Object{
struct TypeInformation;
static const TypeInformation &GetTypeInformationStatic() const
{
return GetTypeInformationMain1();
}
virtual const TypeInformation &GetTypeInformation() const
{
return GetTypeInformationMain1();
}
protected:
static const TypeInformation &GetTypeInformationMain1(); // Main function
};
struct SomeObject : public Object {
static const TypeInformation &GetTypeInformationStatic() const
{
return GetTypeInformationMain2();
}
virtual const TypeInformation &GetTypeInformation() const
{
return GetTypeInformationMain2();
}
protected:
static const TypeInformation &GetTypeInformationMain2(); // Main function
};
No, this is not possible, because static member functions lack a this pointer. And static members (both functions and variables) are not really class members per-se. They just happen to be invoked by ClassName::member, and adhere to the class access specifiers. Their storage is defined somewhere outside the class; storage is not created each time you instantiated an object of the class. Pointers to class members are special in semantics and syntax. A pointer to a static member is a normal pointer in all regards.
virtual functions in a class needs the this pointer, and is very coupled to the class, hence they can't be static.
It's not possible, but that's just because an omission. It isn't something that "doesn't make sense" as a lot of people seem to claim. To be clear, I'm talking about something like this:
struct Base {
static virtual void sayMyName() {
cout << "Base\n";
}
};
struct Derived : public Base {
static void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
Derived::sayMyName(); // Also would work.
}
This is 100% something that could be implemented (it just hasn't), and I'd argue something that is useful.
Consider how normal virtual functions work. Remove the statics and add in some other stuff and we have:
struct Base {
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
}
This works fine and basically what happens is the compiler makes two tables, called VTables, and assigns indices to the virtual functions like this
enum Base_Virtual_Functions {
sayMyName = 0;
foo = 1;
};
using VTable = void*[];
const VTable Base_VTable = {
&Base::sayMyName,
&Base::foo
};
const VTable Derived_VTable = {
&Derived::sayMyName,
&Base::foo
};
Next each class with virtual functions is augmented with another field that points to its VTable, so the compiler basically changes them to be like this:
struct Base {
VTable* vtable;
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
VTable* vtable;
void sayMyName() override {
cout << "Derived\n";
}
};
Then what actually happens when you call b->sayMyName()? Basically this:
b->vtable[Base_Virtual_Functions::sayMyName](b);
(The first parameter becomes this.)
Ok fine, so how would it work with static virtual functions? Well what's the difference between static and non-static member functions? The only difference is that the latter get a this pointer.
We can do exactly the same with static virtual functions - just remove the this pointer.
b->vtable[Base_Virtual_Functions::sayMyName]();
This could then support both syntaxes:
b->sayMyName(); // Prints "Base" or "Derived"...
Base::sayMyName(); // Always prints "Base".
So ignore all the naysayers. It does make sense. Why isn't it supported then? I think it's because it has very little benefit and could even be a little confusing.
The only technical advantage over a normal virtual function is that you don't need to pass this to the function but I don't think that would make any measurable difference to performance.
It does mean you don't have a separate static and non-static function for cases when you have an instance, and when you don't have an instance, but also it might be confusing that it's only really "virtual" when you use the instance call.
Well , quite a late answer but it is possible using the curiously recurring template pattern. This wikipedia article has the info you need and also the example under static polymorphism is what you are asked for.
This question is over a decade old, but it looks like it gets a good amount of traffic, so I wanted to post an alternative using modern C++ features that I haven't seen anywhere else.
This solution uses CRTP and SFINAE to perform static dispatching. That, in itself, is nothing new, but all such implementations I've found lack strict signature checking for "overrides." This implementation requires that the "overriding" method signature exactly matches that of the "overridden" method. This behavior more closely resembles that of virtual functions, while also allowing us to effectively overload and "override" a static method.
Note that I put override in quotes because, strictly speaking, we're not technically overriding anything. Instead, we're calling a dispatch method X with signature Y that forwards all of its arguments to T::X, where T is to the first type among a list of types such that T::X exists with signature Y. This list of types considered for dispatching can be anything, but generally would include a default implementation class and the derived class.
Implementation
#include <experimental/type_traits>
template <template <class...> class Op, class... Types>
struct dispatcher;
template <template <class...> class Op, class T>
struct dispatcher<Op, T> : std::experimental::detected_t<Op, T> {};
template <template <class...> class Op, class T, class... Types>
struct dispatcher<Op, T, Types...>
: std::experimental::detected_or_t<
typename dispatcher<Op, Types...>::type, Op, T> {};
// Helper to convert a signature to a function pointer
template <class Signature> struct function_ptr;
template <class R, class... Args> struct function_ptr<R(Args...)> {
using type = R (*)(Args...);
};
// Macro to simplify creation of the dispatcher
// NOTE: This macro isn't smart enough to handle creating an overloaded
// dispatcher because both dispatchers will try to use the same
// integral_constant type alias name. If you want to overload, do it
// manually or make a smarter macro that can somehow put the signature in
// the integral_constant type alias name.
#define virtual_static_method(name, signature, ...) \
template <class VSM_T> \
using vsm_##name##_type = std::integral_constant< \
function_ptr<signature>::type, &VSM_T::name>; \
\
template <class... VSM_Args> \
static auto name(VSM_Args&&... args) \
{ \
return dispatcher<vsm_##name##_type, __VA_ARGS__>::value( \
std::forward<VSM_Args>(args)...); \
}
Example Usage
#include <iostream>
template <class T>
struct Base {
// Define the default implementations
struct defaults {
static std::string alpha() { return "Base::alpha"; };
static std::string bravo(int) { return "Base::bravo"; }
};
// Create the dispatchers
virtual_static_method(alpha, std::string(void), T, defaults);
virtual_static_method(bravo, std::string(int), T, defaults);
static void where_are_the_turtles() {
std::cout << alpha() << std::endl; // Derived::alpha
std::cout << bravo(1) << std::endl; // Base::bravo
}
};
struct Derived : Base<Derived> {
// Overrides Base::alpha
static std::string alpha(){ return "Derived::alpha"; }
// Does not override Base::bravo because signatures differ (even though
// int is implicitly convertible to bool)
static std::string bravo(bool){ return "Derived::bravo"; }
};
int main() {
Derived::where_are_the_turtles();
}
I think what you're trying to do can be done through templates. I'm trying to read between the lines here. What you're trying to do is to call a method from some code, where it calls a derived version but the caller doesn't specify which class. Example:
class Foo {
public:
void M() {...}
};
class Bar : public Foo {
public:
void M() {...}
};
void Try()
{
xxx::M();
}
int main()
{
Try();
}
You want Try() to call the Bar version of M without specifying Bar. The way you do that for statics is to use a template. So change it like so:
class Foo {
public:
void M() {...}
};
class Bar : public Foo {
public:
void M() {...}
};
template <class T>
void Try()
{
T::M();
}
int main()
{
Try<Bar>();
}
No, Static member function can't be virtual .since virtual concept is resolved at run time with the help of vptr, and vptr is non static member of a class.due to that static member function can't acess vptr so static member can't be virtual.
No, its not possible, since static members are bound at compile time, while virtual members are bound at runtime.
If your desired use for a virtual static is to be able to define an interface over the static section of a class then there is a solution to your problem using C++20 concept's.
class ExBase { //object properties
public: virtual int do(int) = 0;
};
template <typename T> //type properties
concept ExReq = std::derived_from<T, ExBase> && requires(int i) { //~constexpr bool
{
T::do_static(i) //checks that this compiles
} -> std::same_as<int> //checks the expression type is int
};
class ExImpl : virtual public ExBase { //satisfies ExReq
public: int do(int i) override {return i;} //overrides do in ExBase
public: static int do_static(int i) {return i;} //satisfies ExReq
};
//...
void some_func(ExReq auto o) {o.do(0); decltype(o)::do_static(0);}
(this works the same way on members aswell!)
For more on how concepts work: https://en.cppreference.com/w/cpp/language/constraints
For the standard concepts added in C++20: https://en.cppreference.com/w/cpp/concepts
First, the replies are correct that what the OP is requesting is a contradiction in terms: virtual methods depend on the run-time type of an instance; static functions specifically don't depend on an instance -- just on a type. That said, it makes sense to have static functions return something specific to a type. For example, I had a family of MouseTool classes for the State pattern and I started having each one have a static function returning the keyboard modifier that went with it; I used those static functions in the factory function that made the correct MouseTool instance. That function checked the mouse state against MouseToolA::keyboardModifier(), MouseToolB::keyboardModifier(), etc. and then instantiated the appropriate one. Of course later I wanted to check if the state was right so I wanted write something like "if (keyboardModifier == dynamic_type(*state)::keyboardModifier())" (not real C++ syntax), which is what this question is asking.
So, if you find yourself wanting this, you may want to rething your solution. Still, I understand the desire to have static methods and then call them dynamically based on the dynamic type of an instance. I think the Visitor Pattern can give you what you want. It gives you what you want. It's a bit of extra code, but it could be useful for other visitors.
See: http://en.wikipedia.org/wiki/Visitor_pattern for background.
struct ObjectVisitor;
struct Object
{
struct TypeInformation;
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v);
};
struct SomeObject : public Object
{
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v) const;
};
struct AnotherObject : public Object
{
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v) const;
};
Then for each concrete Object:
void SomeObject::accept(ObjectVisitor& v) const {
v.visit(*this); // The compiler statically picks the visit method based on *this being a const SomeObject&.
}
void AnotherObject::accept(ObjectVisitor& v) const {
v.visit(*this); // Here *this is a const AnotherObject& at compile time.
}
and then define the base visitor:
struct ObjectVisitor {
virtual ~ObjectVisitor() {}
virtual void visit(const SomeObject& o) {} // Or = 0, depending what you feel like.
virtual void visit(const AnotherObject& o) {} // Or = 0, depending what you feel like.
// More virtual void visit() methods for each Object class.
};
Then the concrete visitor that selects the appropriate static function:
struct ObjectVisitorGetTypeInfo {
Object::TypeInformation result;
virtual void visit(const SomeObject& o) {
result = SomeObject::GetTypeInformation();
}
virtual void visit(const AnotherObject& o) {
result = AnotherObject::GetTypeInformation();
}
// Again, an implementation for each concrete Object.
};
finally, use it:
void printInfo(Object& o) {
ObjectVisitorGetTypeInfo getTypeInfo;
Object::TypeInformation info = o.accept(getTypeInfo).result;
std::cout << info << std::endl;
}
Notes:
Constness left as an exercise.
You returned a reference from a static. Unless you have a singleton, that's questionable.
If you want to avoid copy-paste errors where one of your visit methods calls the wrong static function, you could use a templated helper function (which can't itself be virtual) t your visitor with a template like this:
struct ObjectVisitorGetTypeInfo {
Object::TypeInformation result;
virtual void visit(const SomeObject& o) { doVisit(o); }
virtual void visit(const AnotherObject& o) { doVisit(o); }
// Again, an implementation for each concrete Object.
private:
template <typename T>
void doVisit(const T& o) {
result = T::GetTypeInformation();
}
};
With c++ you can use static inheritance with the crt method. For the example, it is used widely on window template atl & wtl.
See https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
To be simple, you have a class that is templated from itself like class myclass : public myancestor. From this point the myancestor class can now call your static T::YourImpl function.
I had a browse through the other answers and none of them seem to mention virtual function tables (vtable), which explains why this is not possible.
A static function inside a C++ class compiles to something which is effectively the same as any other function in a regular namespace.
In other words, when you declare a function static you are using the class name as a namespace rather than an object (which has an instance, with some associated data).
Let's quickly look at this...
// This example is the same as the example below
class ExampleClass
{
static void exampleFunction();
int someData;
};
// This example is the same as the example above
namespace ExampleClass
{
void exampleFunction();
// Doesn't work quite the same. Each instance of a class
// has independent data. Here the data is global.
int someData;
}
With that out of the way, and an understanding of what a static member function really is, we can now consider vtables.
If you declare any virtual function in a class, then the compiler creates a block of data which (usually) precedes other data members. This block of data contains runtime information which tells the program at runtime where in memory it needs to jump to in order to execute the correct (virtual) function for each instance of a class which might be created during runtime.
The important point here is "block of data". In order for that block of data to exist, it has to be stored as part of an instance of an object (class). If your function is static, then we already said it uses the name of the class as a namespace. There is no object associated with that function call.
To add slightly more detail: A static function does not have an implicit this pointer, which points to the memory where the object lives. Because it doesn't have that, you can't jump to a place in memory and find the vtable for that object. So you can't do virtual function dispatch.
I'm not an expert in compiler engineering by any means, but understanding things at least to this level of detail is helpful, and (hopefully?) makes it easy to understand why (at least in C++) static virtual does not make sense, and cannot be translated into something sensible by the compiler.
Maybe you can try my solution below:
class Base {
public:
Base(void);
virtual ~Base(void);
public:
virtual void MyVirtualFun(void) = 0;
static void MyStaticFun(void) { assert( mSelf != NULL); mSelf->MyVirtualFun(); }
private:
static Base* mSelf;
};
Base::mSelf = NULL;
Base::Base(void) {
mSelf = this;
}
Base::~Base(void) {
// please never delete mSelf or reset the Value of mSelf in any deconstructors
}
class DerivedClass : public Base {
public:
DerivedClass(void) : Base() {}
~DerivedClass(void){}
public:
virtual void MyVirtualFun(void) { cout<<"Hello, it is DerivedClass!"<<endl; }
};
int main() {
DerivedClass testCls;
testCls.MyStaticFun(); //correct way to invoke this kind of static fun
DerivedClass::MyStaticFun(); //wrong way
return 0;
}
Like others have said, there are 2 important pieces of information:
there is no this pointer when making a static function call and
the this pointer points to the structure where the virtual table, or thunk, are used to look up which runtime method to call.
A static function is determined at compile time.
I showed this code example in C++ static members in class; it shows that you can call a static method given a null pointer:
struct Foo
{
static int boo() { return 2; }
};
int _tmain(int argc, _TCHAR* argv[])
{
Foo* pFoo = NULL;
int b = pFoo->boo(); // b will now have the value 2
return 0;
}