In C++ I'm trying to make a simple state machine for a game, based on classes.
stateMan.setState<mainMenuState>();
I have a class with the declaration as:
class stateManager
{
...
template <class T>
void setState(void);
}
And the test code as:
template <class T>
void stateManager::setState<T>(void)
{
T* blah = new T;
delete blah;
}
And obviously this doesn't work since function template partial specialization ‘setState<T>’ is not allowed.
Would there be a better way to do this besides doing it non-OO?
The definition of the member function template should be this:
template <class T>
void stateManager::setState(void)
{
//...
}
That is, it should be simply setState instead of setState<T>. The latter syntax is used in function template specialization. Since T is a type parameter, the specialization would be considered as function partial template specialization which is not allowed.
Hard to say without the details, but you could do a base State class, and the different states inherit from it.
If you still want to use classes for this, you can see an interesting
example using boost.mpl.
Another option that avoids templates would be to define a pure virtual base class for your game states, and then pass references to different game-states to your function. For instance,
//pure virtual base class that will define the state interfaces
class base_state { /*...*/ };
//a derived state class
class mainMenuState : public base_state { /*...*/ };
class stateManager
{
//...
//you can pass any derived base_state to this function
void setState(base_state* state);
};
Related
I have the following code:
template <typename T>
class A {
public:
virtual void func() {
// Things that don't use T parameter.
}
};
class B : public A<int> {
public:
void func() {
A<int>::func();
// Working...
}
};
Basically, I want to override a virtual function defined in a class template from inside a class that inherits from a specialized version of such template (A).
Does this work in C++? Is it good practice? Also, is it ok to call the overridden method as I did in the overriding one? (please, note that, for compatibility with the toolchain I'm using, this is C++98)
Thank you.
This is kind of a two-part question, but I believe they're very closely related.
Question 1:
I've read on other questions that there are ways to enforce a class in having certain static functions, like such:
class Type{
virtual void staticVirtual() = 0;
};
template<typename T>
class StaticContract{
void staticVirtual(){
T::foo();
}
};
If I made a class that inherited from this contract:
class Example : public StaticContract<Example>{
...
};
Then Example would have to implement a static function foo().
The problem I'm having is if I make a templated class that inherits from the contract:
template <Typename T>
class mTemplateClass :
public StaticContract<mTemplateClass<T>>{
...
}
I don't get any errors for not implementing foo().
How can I enforce a template to have certain static functions that I can call, or is that even possible?
Question 2:
Considering the above question, each StaticContract contains a static instance of a Registration that is instantiated with the type passed, (StaticContract<typename T> and will have a Registration<T>):
template <typename T>
class Registration :
public Registrants
{
public:
Registration() {
vectorOfFunctions->push_back(&T::foo);
}
};
When the class inheriting from StaticContract is not a template, this works fine, but when its a template, it'll never push back an instance of its function, not to mention it doesn't even enforce its implementation.
How can I push back this function from the most derived class?
I have a template class.
template <class A> class TemplateClass
{
//functions
}
and I have the following classes
class B : A
{
//functions
}
class C : A
{
//functions
}
My doubt is why it is not possible to define as below:
TemplateClass<A> *instance;
instance = new TemplateClass<B>; // A is the super class of B
Thanks in advance
A is a base class of B, yes, but TemplateClass<A> is not a base class of TemplateClass<B>.
You're making unfounded assumptions whilst mixing template metaprogramming and OOP.
Two objects using the same template class with different template parameters are not related. A template class initialized using TemplateClass<A> is a completely different type to TemplateClass<B>, the relationship between the A and B classes are not even considered.
Think about it this way. When you create a template class, you're not actually creating a class, you're creating a template for a class. So if you have the following template class:
template <typename T>
class MyTemplate
{
public:
T *m_pFoo;
}
If you use the following code to create two instances of that template class:
MyTemplate<A> aTemplate;
MyTemplate<B> bTemplate;
The compiler (at least conceptually) expands the template to create two separate classes:
class MyTemplate_typenameA
{
public:
A *m_pFoo;
}
class MyTemplate_typenameB
{
public:
B *m_pFoo;
}
Note that these compiler-generated classes don't share any base class, and therefore you can't use them as you might if A and B are related.
I've got a fairly unique situation.
I've got a structure resembling the following code, where a class template inherits from its own template argument, which may be a certain BaseClass, or any of its subclasses.
class BaseClass {
...
virtual void BaseMethod();
};
class DerivedClass {
...
virtual void BaseMethod(); // DerivedClass Overrides some of baseclass's methods
void DerivedMethod(); // And it has a few of its own
};
template <class T>
class ClassTemplate : public T {
...
// Some validation to ensure that this class template extends
// either BaseClass or one of its derived classes
void ValidateTemplate(const BaseClass& c) {}
...
}
The point where this becomes tricky is when I want to take a template class argument that is templated after the baseclass, or one of its subclasses:
void func(ClassTemplate& c) { ... c.BaseMethod(); }
Of course, this doesn't compile as its missing its template arguments. However, I'm looking for a solution that will function like the following, without having to actually specify the following function overloads:
void func(ClassTemplate<BaseClass>& c) { ... c.BaseMethod(); }
void func(ClassTemplate<DerivedClass>& c) { ... c.BaseMethod(); }
On top of that, one of my other classes contains a list of ClassTemplate pointers:
class ClassWithList {
std::list<ClassTemplate<BaseClass>*> l;
...
}
With the above, I want the list l to contain both ClassTemplate<BaseClass> objects, and ClassTemplatE<DerivedClass> objects. This has the same root problem - hoping that the latter could be interpreted as the former, as is the case for most implicit conversions in C++. Is this particular kind of conversion possible to do with templates? Or is there an alternate workaround?
Notes:
In func, none ofDerivedClass's functions are used - just like if I had taken a BaseClass argument, I want to be able to access its public members.
However, it is important that I don't take BaseClass as an argument. This is because I need to access members of the ClassTemplate object, which are unique to ClassTemplate itself.
Additionally, I can't resort to using multiple inheritance (Have DerivedClass subclass both ClassTemplate and BaseClass) as this will result in diamond inheritance, thus creating an inheritance hierarchy too complicated for simple virtual inheritance.
From your description, it sounds like you want a function template:
template <typename T>
void func(ClassTemplate<T>& c) { ... c.BaseMethod(); }
For handling the list case, one option is to have a third class that you use as the interface:
struct ClassTemplateBase {
virtual void doSomething() = 0;
};
template <class T>
class ClassTemplate : public T, public ClassTemplateBase {
// ...
}
then you can have a std::list<ClassTemplateBase *>. This avoids the diamond inheritance issue.
This post is what I just read.
The way he implements Singleton in C++ confuses me. I got several Questions about it and here is his code:
template<typename T>
class Singleton {
public:
static T& getInstance() { //Question 1
return instance;
}
private:
static T instance;
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};
Question
I think we should put the static T& getInstance()'s definition outside of the class body, right?
He tries to make class DebugLog a singleton class, but when he inherits Singleton<DebugLog>, the DebugLog doesn't already exist, right? If right, then how can the template class Singleton instantiate an un-existent class?
1) Nope, it doesn't matter how you structure your code. Singleton isn't a class, by the way: It's a template. Since the full template definition must be visitible at any instantiation site anyway, you might as well define everything inline.
2) class DebugLog : public Singleton<DebugLog> is fine. We are not inheriting from a non-existing class; rather, we are inheriting from the class Singleton<DebugLog>. Templates can be instantiated on incomplete types. (There are several rules what you can and cannot do with such a type parameter.)
For example, template <typename T> class Foo { }; can certainly be instantiated on any type without problem. More interestingly, template <typename T> struct PointerFactory { typedef T * type; }; can be instantiated on any type, complete or not. In the present situation, the purpose of the template parameter in the CRTP is solely to inform the base class of its eventual derived type, so this is entirely fine.
It would certainly be cleaner if the function were defined outside of
the class, and make the code easier to read and to maintain. In this
case, however, the complete class is small enough that the difference
isn't very great, and of course, because we're dealing with a template,
the actual definition still has to be included in every translation unit
which uses it.
The C++ standard doesn't speak of “existence” with regards to classes (or anything
else). At the point of template instantiation, name lookup finds
DebugLog, and finds that it is a class (thus, a type). At that point,
it is an incomplete type, and there are only limited things you can do
with an incomplete type. If the class template which is instantiated
doesn't do anything that requires a complete type (and Singleton
doesn't), then there is no problem. (Note that only the class
definition is instantiated at this point; class member functions will
not be instantiated until they are used.)
I might add that there is still one important thing missing from the
code you posted: there is no definition for the declaration
Singleton::instance. You still need to add a:
template<typename T> T Singleton<T>::instance;
somewhere.
You must use a pointer to T in this case:
template<typename T>
class Singleton {
public:
static T& getInstance() {
static T * instance = NULL;
if (!instance)
instance = new T;
return *instance;
}
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};