Is it possible to write template definition for this data type?
myclass<int, myclass<int> > data;
Second template variable should be optional with default value of the same type.
Clarification
Now I use this definition:
class defaultClass { };
template <typename T, typename C=defaultClass>
class myclass { ... };
I'd like to predefine that defaultClass is myclass<T>
I'd like to implement something like auto implemented properties: the second parameter should be context in which the wrapped variable is defined. If the context is ommited, it should be in the object created by the template class itself. (I realize it could be solved another way, this is just use case.)
Looks very similar to
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
You can do the thing you want by making a class hierarchy with template base type and then each of your classes may be derived from that base like
template<class T> class base { ... };
class derived: public base<derived> {...};
Related
How can I specify template parameter to be of a certain type i-e it must have implemented an interface (the template parameter must be a derived class of a specific base class)
Heres the interface (abstract base class)
class baseActionCounter{
public:
virtual int eat()=0;
virtual int drink()=0;
};
Now I want my template parameter to be of type baseActionCounter
Heres the templated class
//imaginary template syntax in the line below. Is there a way of achieving this behavior?
template <class counterType : baseActionCounter>
class bigBoss{
counterType counter;
public:
int consumerStats(){
//I am able to call member function because I know that counter object has eat() and drink()
//because it implemented baseActionCounter abstract class
return counter.eat() + counter.drink();
}
};
I can also just derive my bigBoss class from baseActionCounter but I want to know how to achieve this behavior with templates.
Also, template specialization is not suitable as there is just one BigBoss class for any implementor of baseActionCounter class.
Yes, you can use std::is_base_of to check the type, e.g.
template <class counterType, std::enable_if_t<std::is_base_of_v<baseActionCounter, counterType>>* = nullptr>
class bigBoss {
Or
template <class counterType>
class bigBoss {
static_assert(std::is_base_of_v<baseActionCounter, counterType>, "counterType must derive from baseActionCounter");
...
};
Or use concept (since C++20).
template <class T>
concept Derived = std::is_base_of_v<baseActionCounter, T>;
template <Derived counterType>
class bigBoss {
BTW: std::is_base_of also returns true if the base class baseActionCounter is specified; if that's not what you want you can combine the condition with std::is_same.
In order to use a library, I need to use different classes that have the same base name. I.e.
MyClass
MyClassImpl
PreMyClass
And so on. in order to use them with template I need pass all these class names.
template <typename T, typename TImpl, typename PreT>
class ClassThatUsesAllTheseObjects
{
public:
ClassThatUsesAllTheseObjects();
private:
T myClass;
TImpl myClassImpl;
PreT myPreClass;
};
It's possibile to obtain the same result giving only the principal MyClass as template argument, building other names when needed?
Am not sure of the settings in your question, but in some cases, you might want to do something like the trait mechanism.
Suppose you write a concrete MyClass, and others like it. For each group of concrete classes, you do something like:
// This is common
template <typename T>
struct foo_traits
{
};
// This is for each set of concrete classes
template<>
struct foo_traits<MyClass>
{
using Impl = MyClassImpl;
using Pre = PreMyClass;
};
...
Then you use the traits class like this:
template <
typename T,
class Impl = typename foo_traits<T>::Impl,
class Pre = typename foo_traits<T>::Pre>
class ClassThatUsesAllTheseObjects
{
public:
ClassThatUsesAllTheseObjects();
private:
T myClass;
Impl myClassImpl;
Pre myPreClass;
};
This allows you to explain what are the "natural friends" of your principal concrete classes.
I can think of two options:
Use a tag to make the difference. So you would have e.g. a template <class T> myClass, a struct impl_t{}, struct pre_t{}, struct base_t{} and then use gthem in this way:
code:
myClass<base_t> ; // instead of plain MyClass
myClass<impl_t> ;// instead of plain MyClassImpl
myClass<pre_t> ; // instead of myPreClass
Template specialization should make their definition easy/possible.
traits, but there is already an answer on that side :-)
I have a template class defined :
template <class T>
class TempClass
{
...
};
If I want to make an object of this class in let's say some MyClass.h to access functions of template class, how shall I pass the argument of the template?
I tried to do the following:
class MyClass{
public:
TempClass<T> temp;
}
Sure, as supposed it does not work, as T is not defined in MyClass, so I am a bit lost how do it correctly.
Thanks.
If you want MyClass to be a template as well, you would do it like this:
template<typename T>
struct MyClass {
TempClass<T> temp;
};
(You could also use class instead of struct, but since all members are public, you don't really need default private.)
If you don't want MyClass to be a template, you will need some concrete type to substitute in for T. For example:
struct MyClass {
TempClass<string> temp;
};
Pedantic: Technically TempClass isn't a template class, it's a class template. A class template isn't actually a class, it's a template that can be used to create individual classes that are themselves template classes. Thus, TempClass is a class template, while TempClass<string> is a template class --- a class that is created by instantiating a template.
Templates are not classes. Are. as it name means, templates wich helps the compiler to create classes. That is, if you have a template class template<typename T> class Foo{};:
template<typename T>
struct Foo
{
T attribute;
};
Its only a template which the compiler uses to generate different versions of Foo, each for a specified type. When you instantiate a template, that is, tells the compiler you need that class generated with a specified type, the compiler generates a version of Foo code replacing the template argument with the specified type:
int main()
{
Foo<int> foo_int_variable;
Foo<bool> foo_bool_variable;
}
The compiler after seeing that two instances, generates code like this:
struct __Foo_int
{
int attribute;
};
struct __Foo_bool
{
bool attribute;
};
So the code of main is translated to this:
int main()
{
__Foo_int foo_int_variable;
__Foo_bool foo_bool_variable;
}
So the answer is: You need to specify what type you need, to let the compiler to generate the correct template instantiation.
If the class that uses Foo, like in your example, don't need a specific instantiation of Foo, needs a generic version of Foo, you could make that class a template too.
You can instantiate your template like this, for example, to instantiate for int:
class MyClass
{
public:
TempClass<int> temp;
};
But if you still want you MYClass to be generic, you can make it template too and define it like this:
template<typename T>
class MyClass
{
public:
TempClass<T> temp;
};
and let the any MyClass object instantiation to define parameter T, for example:
MyClass<int> class;
I am thinking about using curiously recurring template pattern for my application. However, I would like the classes to operate on the user defined types. I would like to understand if it is possible to create a structure similar to the one shown below:
template <class T_leaftype>
class BaseTrajectoryPoint {
};
template <class MyType>
class MyTrajectoryPoint: public BaseTrajectoryPoint<MyTrajectoryPoint> {
private:
MyType A;
};
The code above fails to compile with the following error:
type/value mismatch at argument 1 in template parameter list for ‘template class BaseTrajectoryPoint’
Are there any alternative ways of approaching the problem? I would like to use static polymorphism, but I would prefer to define all possible methods in the base class.
template <class T_leaftype>
class BaseTrajectoryPoint {
};
template <class MyType>
class MyTrajectoryPoint: public BaseTrajectoryPoint<MyTrajectoryPoint<MyType> > {
private:
MyType A;
};
MyTrajectoryPoint isn't a type, it's template; when you pass it as template parameter, it's seen as template<typename> class T>, not template<class T> - and the latter is what your base class is expecting. But MyTrajectoryPoint<MyType> names a type, so you can use it as template parameter of your base class.
Of course, you can change declaration of BaseTrajectoryPoint to template<template<class> class T_leaftype>, but then you would have to use class template as template parameter, never a complete type.
What our friend Griwes said is correct, although if you know that every class that will inherit BaseTrajectoryPoint is a template class, you can do the following:
template<template < class > class TLeaf> // << This means: It is expected a template class as parameter
class BaseTrajectoryPoint{
};
template <class MyType>
class MyTrajectoryPoint: public BaseTrajectoryPoint<MyTrajectoryPoint> >{
private:
MyType A;
};
I was wondering if there could be any way to write a template function in an abstract class, and have it (the template function) automatically instantiated with the type of the derived class?
So you have a class that looks something like this
class A
{
virtual template < typename T>
void vtfunc(void)
};
class B : public A
{
/// No declared members pertaining to this example
}
Then, whenever a class derived from A is declared, it compiles "vtfunc" with itself as the template parameter T.
Then, calling vtfunc() through an interface of A calls the isntance of that function compiled for its derived class B.
Is there any way of doing this, or writing something fiddley that have this effect?
Obviously I am aware that the template parameter could only affect the internals of the class, and not the return type and parameters - they would need to be the same because of the way polymorphism works.
I’m not sure what you’re after but one common pattern is the so-called curiously recurring template pattern; here, the base class itself is the template, not its member functions. In other words:
template <typename T>
class A
{
virtual void vtfunc(void)
};
class B : public A<B>
{
…
};
Consider using a non-member function instead.