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.
Related
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?
Is it possible to declare a templated class in C++ along with the classes it inherits from? Basically I want to give the compiler a hint, that my templated class will always inherit another at declaration time.
Maybe some code will clear up why this is a problem for me:
template<typename T>
class GrandparentClass
{
public:
T grandparentMember;
};
//this needs to be only a declaration, since I do not want classes of ParentClass with random T
template<typename T>
class ParentClass : public GrandparentClass<T>
{
};
// this does not work:
//template<typename T>
//class ParentClass : public GrandparentClass<T>;
// this does not either, because then the child class cannot access the variable from the grandparent class
//template<typename T>
//class ParentClass;
template<>
class ParentClass<int> : public GrandparentClass<int>
{
public:
ParentClass()
{
grandparentMember = 5;
}
};
template <typename T>
class ChildClass : public ParentClass<T>
{
public:
void foo()
{
std::cout << grandparentMember << "\n";
}
};
Also, I cannot use C++ 11.
EDIT:
I found an easy way out of this:
template<typename T>
class ParentClass : public GrandparentClass<T>
{
public:
ParentClass() { ParentClass::CompilerError(); };
};
Just do not define CompilerError() method in the class and everything's fine.
A class declaration is only really useful for non-value variable declarations, like pointers and references. You can't access the class members or even instantiate it, though. Even if you knew that a declared class inherits from some other one, you still wouldn't necessarily be able to utilize that information in any way.
As such, it's only important for the compiler to know what the class inherits from once it learns its full definition.
After clarification in comments: if you want to prevent instantiation of a class template with some types, its definition is the place to do it. A simple static_assert inside the class body will do the trick; Boost.StaticAssert or older SFINAE tricks will do the job for pre-C++11 code.
If you are happy with delaying the error to link-time, rather than compile time, you can declare all the member functions of parent in parent.h, provide definitions in parent.cpp, and explicitly instantiate the finite list of classes that you want.
Parent.h
template<typename T>
class ParentClass : public GrandparentClass<T>
{
ParentClass();
};
class ParentClass<int>;
class ParentClass<long int>; // or whatever
Parent.cpp
template <typename T>
ParentClass::ParentClass() : grandparentMember(5) {}
Is there a way to define a template class that can be used only with derived classes from a particular class hierarchy?
Say I have Animal base class
class Animal{
public:
virtual ~Animal();
virtual void shout() = 0;
};
and Dog, Cat,Tiger are derived classes
class Dog : public Animal{
public:
virtual void shout(){
cout<<"Bark";
}
}
class Cat : public Animal{
public:
virtual void shout()
{
cout<<"Meow";
}
}
I need to define a template class say 'AnimalTemplate' that can be used ONLY with the derived class of Animal, so if I try to do 'AnimalTemplate< Duck >', I should get compilation error( or some error ), even if Duck has a method shout() defined in it.
(This question is mainly for me to understanding if we can mix OO paradigm with Generic programming)
Two forms of this immediately come to mind:
SFINAE
template<typename T,
typename = typename std::enable_if<std::is_base_of<Animal,T>::value>::type>
class AnimalTemplate
{
public:
AnimalTemplate() {}
};
static_assert
template<typename T>
class AnimalTemplate
{
public:
static_assert(std::is_base_of<Animal,T>::value, "T must be derived from Animal");
AnimalTemplate() {}
};
The latter is friendlier in telling you why it failed, obviously.
You can simple define your template in such a way that it uses the template argument as an Animal. For example:
template <typename T,
bool = sizeof(*static_cast<Animal**>(0) = static_cast<T*>(0))>
class AnimalTemplate
{
// whatever
};
Producing an error in case a template argument doesn't match is generally fairly trivial. If there is any method which is always instantiated, e.g., the destructor, that could be a palce where the check could go, too.
If animalTemplate is a function template you could just do:
template<typename T> void animalTemplate(T animal_candidate){
auto& animal= static_cast<Animal&>(animal_candidate);
animal.shout();
}
Most often templates trust the user to use the correct input. This is known as duck typing. (suiting for your case!) There is work for future C++ on defining Concepts, which may be used to specify what kind of input a template can take.
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);
};
I am designing a template class Policy which needs to be able to handle pointers to other classes.
template <class P>
class Policy
{
private:
const P *state;
public:
Policy (P const* s) : state(s){};
};
This works fine.
Now I want to inherit from the above template class and create new subclasses:
class Greedy : public Policy<???>
{
public:
template <typename P> Greedy (P const* s) : Policy(s) {}:
};
class Explora : public Policy<???>
{
public:
template <typename P> Explora (P const* s) : Policy(s) {}:
};
Problem is that when defining those classes I do not know what type they will be using for the base template class. Is this even possible to do ?
I want the type obtained from the inherited class constructor (probably templated), and then pass it to the base class construtor.
Can I do that ? If yes, how ? typedefining enums ?
I have seen this question but it doesn't in my opinion really answer the question.
Make them template classes:
template <typename P>
class Greedy : public Policy<P>
{
// now you know
};
You can certainly do it (see GMan's answer for the correct parametrization of the derived type), but bear in mind that you will get entirely independent class hierarchies for every type P. You are not magically creating a super class that has an arbitrary number of member types.
Consider templates as a code generation tool. They do not create a "type-generic type", rather they create lots of parallel instances of concrete, static types at compile time following a generic pattern.
If you truly want one single common base type, perhaps you can make the type of state polymorphic:
class Policy // no template
{
StateBase * state;
public:
Policy(StateBase * s) : state(s) { }
};
Then all your derived classes can access the states' common interface.