How would I do to extend a template class, for example vector? The below code does not work. The compiler whines about 'Vector' not being a template.
template <typename T>
class Vector<T> : public std::vector<T>
{
public:
void DoSomething()
{
// ...
}
};
Your syntax is wrong; you need to use:
template <typename T>
class Vector : public std::vector<T>
That said, you should not extend the standard library containers via inheritance, if for no other reason then because they do not have virtual destructors and it is therefore inherently unsafe.
If you want to "enhance" std::vector, do so using composition (i.e., with a member variable of std::vector type) or use non-member functions to provide your additional functionality.
This has nothing to do with extending another class. The problem is your own derived class.
You define a class template like this:
template <typename T>
class Vector
{
...
and not
template <typename T>
class Vector<T>
{
...
Related
So I have a simple template class with multiple classes inheriting different types of it.
template<typename T> class root {
T value;
};
class body : public root<int> {
/* some code */
};
/*some more classes that inherits root*/
and later down in the file, I need to reference all classes that inherits from root
concept _bcie = std::is_base_of_v<root, body>
and it gives me the error use of class template 'root' requires template arguments
But I want to reference ALL classes that inherits from the root
Is there a way to just use the class without providing a template argument?
Make root derive from another higher non-template base class, and check against that class.
The simple way is to use template lambda
template<typename T>
class root {
T value;
};
template<class T>
concept is_derived_from_root = requires (const T& t) {
[]<class U>(const root<U>&){}(t);
};
Demo
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.
I am trying to inherit the std::vector class template into my membvec class template as public. And I want to use it as e.g. say membvec<float> mymemb(10) with the intention of creating my membvec variable mymemb containing 10 elements.
But I can't figure out how to write the templatised declaration of the public inheritance. What I am doing is the following, but all in vain.
template <typename T, template <typename T> class std::vector = std::vector<T>>
//error above: expected '>' before '::' token
class membvec: public std::vector<T>
{
const membvec<T> operator-() const; // sorry the previous version was a typo
//error above: wrong number of template arguments (1, should be 2)
...
};
I think you're looking for something like the below, but seriously don't do it. If you ever pass your class as its parent std::vector, there is no virtual interface to allow your class to provide any benefit whatsoever. And if you don't need to substitute for a std::vector then there's no need to inherit from it. Prefer free function algorithms or containing the std::vector as a member in your class instead.
#include <vector>
template <typename T>
class membvec: public std::vector<T>
{
// Don't need <T> in class scope, must return by value.
membvec operator+() const;
};
int main()
{
membvec<int> foo;
}
Perhaps you want something like this:
#include <vector>
template <typename T, template <typename T, class Allocator> class Vec = std::vector>
class membvec: public Vec<T, std::allocator<T>>
{
public:
// This is the signature in your question, but it's questionable.
const membvec<T, Vec> &operator+(int x) const
{
// You obviously want to change this.
return *this;
}
};
You can then use it regularly:
int main()
{
membvec<char> foo;
foo + 3;
}
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;
};
This occured in the line of thought following Template specialization or conditional expressions?.
I am using template specialisation in a project of mine and came across this example from Stroustrup: Matrix.h, where he declares a MatrixBase template class
template<class T> class Matrix_base
for common elements and a Matrix template class
template<class T = double, int D = 1> class Matrix
as a "prop" (whatever that is) for specialisations. He declares the constructor as private so that only specialisations can be instanciated. These are declared:
template<class T> class Matrix<T,1> : public Matrix_base<T> {...};
template<class T> class Matrix<T,2> : public Matrix_base<T> {...};
template<class T> class Matrix<T,3> : public Matrix_base<T> {...};
My question is: In this case, what is the advantage of specialisation? Obviously there is no code that the three specialisations have in common, so why not cut out the general template and declare:
template<class T> class Matrix_1<T> : public Matrix_base<T> {...};
template<class T> class Matrix_2<T> : public Matrix_base<T> {...};
template<class T> class Matrix_3<T> : public Matrix_base<T> {...};
?
Because by having the second template parameter, one allows for specializations as well as a general, non-specialized implementation. So
Matrix<float, 1000> m;
might do something reasonable but non specialized, whereas you would have to define a Matrix_1000<T>.
Edit: the first point applies in general, but not to this particular case, where the general case has a private constructor.
Furthermore, it allows you to do stuff like
Matrix<double, SOME_CONSTANT> m;
which you cannot do with your _N solution.
Basically the answer is that you can use the template in generic code. You can use a compile time constant to change the behavior of the program, or you can write generic code that will handle different versions of the Matrix class that could not be handled if the types had different names:
template <typename T, int D>
void print( std::ostream& o, Matrix<T,D> const & m ) { ...
That is, even though you need to explicitly create the different types, the specialization mechanism allows you to provide a single name that can be used generically to manage the different types as if they are just variants of one single type.