Using template argument of base class in derived class - c++

Consider the following situation in C++:
template<int n>
class Base { ... };
class Derived3 : public Base<3> {
// a complicated body, making use of n=3
};
class Derived7 : public Base<7> {
// a completely different body, making use of n=7
};
Inside of the Derived3 member functions, I would like to explicitly use n=3, and inside Derived7, n=7, without hardcoding the numbers, i.e., still referring to something like a template argument n. The following options come to my mind:
Also templating the derived classes on n, and then using typedef. This way, the derived classes know n:
template<int n>
class DerivedTemplate3 : public Base<n> { ... };
typedef DerivedTemplate3<3> Derived3;
template<int n>
class DerivedTemplate7 : public Base<n> { ... };
typedef DerivedTemplate7<7> Derived7;
The problem with this is that DerivedTemplateX makes sense for nothing but n=X, so this feels like abusing the template paradigm.
Using a static const member to store n in Base, and referring to that in the derived classes:
template<int n>
class Base {
protected:
static const int nn = n;
...
};
class Derived3 : public Base<3> {
// refer to nn=3
};
class Derived7 : public Base<7> {
// refer to nn=7
};
The problem here is that I seemingly can't use the same identifier (nn vs. n). Also, I'm not sure whether this will allow me to use nn as a template argument for members of the derived classes.
So: how can this be implemented in a non-redundant, efficient way? Maybe using some kind of static const int as a member somewhere?

The standard practice is to use an uppercase letter for the template parameter, then a static const value in lowercase:
template<int N>
class Base {
protected:
static const int n = N;
...
};
Then you use the lowercase static const value n everywhere - don't use N anywhere else.
Also, I'm not sure whether this will allow me to use nn as a template argument for members of the derived classes.
It is a constant expression and so it can be used as a template argument.

Does this work for you?
template<int n>
class Base {
protected:
static const int MyN = n;
};
class Derived3 : public Base<3> {
void f()
{
std::cout << MyN;
}
};
class Derived7 : public Base<7> {
void f()
{
std::cout << MyN;
}
};
int main()
{
}

Related

Way to call a static method of a class template without specifying an instantiation?

Is there any way to define a static method in a class template which can be then be called without specifying the instantiation?
I think this could be useful in cases where you have some auxiliary static function, which logically belongs in a class (which happens to be a template one), but doesn't depend on the template parameter.
I don't mind either:
Having the same static method (including address and all) for all
instantiations, or
Having a separate static method for each instantiation, but be able to call the static method without
specifying an instantiation where I call the method (some default
would be called).
e.g.
template<typename T> class C {
public:
static int func() { return 0; }
};
int main()
{
// This works.
return C<int>::func();
// These don't work.
// return C<>::func();
// return C::func();
}
The simplest solution is probably to have the static function belong in a base class, and then the template derives from the base:
struct CBase {
static int func() { return 0; }
};
template<typename T> class C : public CBase {
public:
};
int main()
{
// This works.
return C<int>::func();
// This will work too:
return CBase::func();
}
You can use inheritance which will also remove the duplication of any non static functions ( that also don't care about the template type ) in your binary, i.e:
class A {
public:
static int func() { return 0; }
};
template<typename T>
class B : A {
};
If you want to get C or C<> to work you can either rely on a base non-template class that contains the given function or use template specializations as it follows:
template<typename...>
struct C;
template<>
struct C<> {
static int func() { return 0; }
};
template<typename T>
struct C<T>: C<> {
// all the other things around...
};
int main() {
C<int>::func();
C<>::func();
}
For you don't provide a definition for the primary template, accepted specializations are:
C<> that contains only the given function
C<T> that accepts only a parameter as it was in the original example
See it on wandbox.
If you can't use variadic templates, you can still do something similar with a custom type.
As an example:
struct func_only {};
template<typename T = func_only>
struct C;
template<>
struct C<func_only> {
static int func() { return 0; }
};
template<typename T>
struct C: C<func_only> {
// all the other things around...
};
int main() {
C<int>::func();
C<>::func();
}
That being said, make it a free function looks to me as the best solution anyway.
How would that work? You typically depend on the type in your static functions too.
template<typename T> class C {
public:
static int func() { return sizeof(T); }
};
If they do not depend on it, you should probably make them free functions, or static members of a base class of this class.

C++:: How to only define once, a common function of different classes inheriting the same interface? [duplicate]

Is it possible to find the size of a derived class object using a base class pointer, when you don't know the derived type.
Thank you.
There's no direct way, but you can write a virtual size() method child classes can implement. An intermediary templates class can automate the leg work.
struct base {
virtual size_t size() const =0;
virtual ~base() { }
};
template<typename T>
struct intermediate : base {
virtual size_t size() const { return sizeof(T); }
};
struct derived : intermediate<derived>
{ };
This does require your hierarchy be polymorphic... however, requesting behavior based on the dynamic type of an object rather than its static type is part of the definition of polymorphic behavior. So this won't add a v-table to the average use case, since at the very least you probably already have a virtual destructor.
This particular implementation does limit your inheritance tree to a single level without getting into multiple inheritance [ie, a type derived from derived will not get its own override of size]. There is a slightly more complex variant that gets around that.
struct base { /*as before */ };
template<typename Derived, typename Base>
struct intermediate : Base {
virtual size_t size() const { return sizeof(Derived); }
};
struct derived : intermediate<derived, base>
{ };
struct further_derived : intermediate<further_derived, derived>
{ };
Basically, this inserts an intermediate in between each actual layer of your hierarchy, each overriding size with the appropriate behavior, and deriving from the actual base type. Repeat ad nauseum.
//what you want
base >> derived
>> more_deriveder
>> most_derivedest
//what you get
base >> intermediate<derived, base>
>> derived >> intermediate<more_deriveder, derived>
>> more_deriveder >> intermediate<most_derivedest, more_deriveder>
>> most_derivedest
Several mixin-type libraries make use of such a scheme, such that the mixins can be added to an existing hierarchy without introducing multiple inheritance. Personally, I rarely use more than a single level of inheritance, so I don't bother with the added complexity, but your mileage may vary.
I don't think it can be done, because sizeof works on compile time types. You could define a virtual Size function in the base class and override it for each derived class.
Due to lack of reflection in C++, this is not generally possible with arbitrary classes at a whim. There are some workarounds however. You can write a virtual size() method as others have suggested. You can also use the Curiously Recurring Template Pattern, aka inheriting from Register<T> as well but I wouldn't recommend it, vtable costs 4 bytes per object, subclasses of T report incorrect size and correcting it results in multiple inheritance.
The best way would be to use a class to register, store and query dynamic size information, without modifying the class you want to query:
EDIT: As it turns out, due to the inconsistent semantics of typeid, it still needs classes with vtables, see the comments.
#include <cstddef>
#include <exception>
#include <iostream>
#include <map>
#include <typeinfo>
using namespace std;
class ClassNotFoundException
: public exception
{};
class Register
{
public:
template <class T>
static void reg (T* = NULL)
{
// could add other qualifiers
v[&typeid(T)] = sizeof(T);
v[&typeid(const T)] = sizeof(T);
v[&typeid(T*)] = sizeof(T);
v[&typeid(const T*)] = sizeof(T);
}
template <class T>
static int getSize (const T& x)
{
const type_info* id = &typeid(x);
if( v.find(id) == v.end() ){
throw ClassNotFoundException();
}
return v[id];
}
template <class T>
static int getSize (T* x)
{
return getSize(*x);
}
template <class T>
static int getSize (const T* x)
{
return getSize(*x);
}
protected:
static map<const type_info*, int> v;
};
map<const type_info*, int> Register::v;
class A
{
public:
A () : x () {}
virtual ~A () {}
protected:
int x;
};
class B
: public A
{
public:
B() : y () {}
virtual ~B () {}
protected:
int y;
};
int main ()
{
Register::reg<A>();
Register::reg<B>();
A* a = new B();
const A* b = new B();
cout << Register::getSize(a) << endl;
cout << Register::getSize(b) << endl;
}
Considering the nice answer of #Dennis Zickefoose, there's a case where you can implement multiple levels of inheritance which requires you neither to have virtual functions nor an intermediate class between each layer of inheritance and the added complexity.
And that's when all the intermediate (non-leaf) classes in the inheritance hierarchy are abstract classes, that is, they are not instantiated.
If that's the case, you can write the non-leaf abstract classes templated (again) on derived concrete types.
The example below demonstrates this:
template <class TDerived>
class Shape // Base
{
public:
float centerX;
float centerY;
int getSize()
{ return sizeof(TDerived); }
void demo()
{
std::cout
<< static_cast<TDerived*>(this)->getSize()
<< std::endl;
}
};
class Circle : public Shape<Circle>
{
public:
float radius;
};
class Square : public Shape<Square>
{
// other data...
};
template <class TDerived>
class Shape3D : public Shape<TDerived>
// Note that this class provides the underlying class the template argument
// it receives itself, and note that Shape3D is (at least conceptually)
// abstract because we can't directly instantiate it without providing it
// the concrete type we want, and because we shouldn't.
{
public:
float centerZ;
};
class Cube : public Shape3D<Cube>
{
// other data...
};
class Polyhedron : public Shape3D<Polyhedron>
{
public:
typedef float Point3D[3];
int numPoints;
Point3D points[MAX_POINTS];
int getSize() // override the polymorphic function
{ return sizeof(numPoints) + numPoints * sizeof(Point3D); }
// This is for demonstration only. In real cases, care must be taken about memory alignment issues to correctly determine the size of Polyhedron.
};
Sample usage:
Circle c;
c.demo();
Polyhedron p;
p.numPoints = 4;
p.demo();

C++ class template for similar classes

I have a socket data type class that is used to read and parse a value from socket stream (may be used for file too).
Let my class be mc_double:
class mc_double {
private:
double value;
public:
bool read(socket);
write(double);
}
Actual class is more complicated, but this is the principle. Now, I need to parse float from the stream. Float is way similar to double, so is already implemented int. Could't I merge this class definitions, with all double, int and float somehow templated?
This is what I mean:
class mc_<typename = double or int or float> {
private:
typename value;
public:
bool read(socket);
write(typename);
}
Some methods would be then defined individualy as mc_double::method() others would be same for all types: mc_typename::general_method(). Also, for some I'd need just minor changes in code:
typename mc_typename::return_value() {
return val;
}
Or the constructor:
mc_typename::mc_typename(<int, long, char, double> number) {
val = (typename)number;
}
The result should be three classes - mc_int, mc_float and mc_double.
I have found the official C++ template docs, but I only figured out the last part of my question - I can create a function that accepts multiple data types. The rest does not seem to be that easy.
You could make your class a class template:
template<typename T, bool base = true>
class mc {
protected:
T value;
public:
bool read(socket);
write(T);
};
This class will contain the member function that are common for all types T. Then, you could specialize this class templates separately for different types and let them inherit from mc<T, true>:
template<>
class mc<double, true> : public mc<double, false> {
public:
// Member functions for double only...
};
template<>
class mc<int, true> : public mc<int, false> {
public:
// Member functions for int only...
};
Make sure the non-public member data of the primary class template are made protected if you want derived classes to access them.
You could then instantiate them this way:
mc<double> m;
mc<int> m;
// ...
If you really want to use the mc_double and mc_int names, then you could either:
a) Create type aliases for them:
typedef mc<double> mc_double;
typedef mc<int> mc_int;
b) Change the design of the class template to not use specialization and have one single template parameter, and create the derived classes independently:
template<typename T>
class mc {
protected:
T value;
public:
bool read(socket);
write(T);
};
class mc_double : public mc<double> {
public:
// Member functions for double only...
};
class mc_int: public mc<int> {
public:
// Member functions for int only...
};
You could use templates in the class definition as follows:
template <typename T>
class mc
{
public:
bool write(T _val);
private:
T mVal;
};
but you can't as easily specialize some methods but not others based on the type of T (i.e., you have to specialize the entire class, not just one method). You could solve this with some sort of inheritance hierarchy, where methods that are the same regardless of the type are in the base, and the specialization is in derived classes. So keep the above (assuming write is one that doesn't change) and create:
class mc_double : public mc<double>
{
public:
void doSomethingSpecific() { /* code specific for 'doubles' */ }
};

find size of derived class object using base class pointer

Is it possible to find the size of a derived class object using a base class pointer, when you don't know the derived type.
Thank you.
There's no direct way, but you can write a virtual size() method child classes can implement. An intermediary templates class can automate the leg work.
struct base {
virtual size_t size() const =0;
virtual ~base() { }
};
template<typename T>
struct intermediate : base {
virtual size_t size() const { return sizeof(T); }
};
struct derived : intermediate<derived>
{ };
This does require your hierarchy be polymorphic... however, requesting behavior based on the dynamic type of an object rather than its static type is part of the definition of polymorphic behavior. So this won't add a v-table to the average use case, since at the very least you probably already have a virtual destructor.
This particular implementation does limit your inheritance tree to a single level without getting into multiple inheritance [ie, a type derived from derived will not get its own override of size]. There is a slightly more complex variant that gets around that.
struct base { /*as before */ };
template<typename Derived, typename Base>
struct intermediate : Base {
virtual size_t size() const { return sizeof(Derived); }
};
struct derived : intermediate<derived, base>
{ };
struct further_derived : intermediate<further_derived, derived>
{ };
Basically, this inserts an intermediate in between each actual layer of your hierarchy, each overriding size with the appropriate behavior, and deriving from the actual base type. Repeat ad nauseum.
//what you want
base >> derived
>> more_deriveder
>> most_derivedest
//what you get
base >> intermediate<derived, base>
>> derived >> intermediate<more_deriveder, derived>
>> more_deriveder >> intermediate<most_derivedest, more_deriveder>
>> most_derivedest
Several mixin-type libraries make use of such a scheme, such that the mixins can be added to an existing hierarchy without introducing multiple inheritance. Personally, I rarely use more than a single level of inheritance, so I don't bother with the added complexity, but your mileage may vary.
I don't think it can be done, because sizeof works on compile time types. You could define a virtual Size function in the base class and override it for each derived class.
Due to lack of reflection in C++, this is not generally possible with arbitrary classes at a whim. There are some workarounds however. You can write a virtual size() method as others have suggested. You can also use the Curiously Recurring Template Pattern, aka inheriting from Register<T> as well but I wouldn't recommend it, vtable costs 4 bytes per object, subclasses of T report incorrect size and correcting it results in multiple inheritance.
The best way would be to use a class to register, store and query dynamic size information, without modifying the class you want to query:
EDIT: As it turns out, due to the inconsistent semantics of typeid, it still needs classes with vtables, see the comments.
#include <cstddef>
#include <exception>
#include <iostream>
#include <map>
#include <typeinfo>
using namespace std;
class ClassNotFoundException
: public exception
{};
class Register
{
public:
template <class T>
static void reg (T* = NULL)
{
// could add other qualifiers
v[&typeid(T)] = sizeof(T);
v[&typeid(const T)] = sizeof(T);
v[&typeid(T*)] = sizeof(T);
v[&typeid(const T*)] = sizeof(T);
}
template <class T>
static int getSize (const T& x)
{
const type_info* id = &typeid(x);
if( v.find(id) == v.end() ){
throw ClassNotFoundException();
}
return v[id];
}
template <class T>
static int getSize (T* x)
{
return getSize(*x);
}
template <class T>
static int getSize (const T* x)
{
return getSize(*x);
}
protected:
static map<const type_info*, int> v;
};
map<const type_info*, int> Register::v;
class A
{
public:
A () : x () {}
virtual ~A () {}
protected:
int x;
};
class B
: public A
{
public:
B() : y () {}
virtual ~B () {}
protected:
int y;
};
int main ()
{
Register::reg<A>();
Register::reg<B>();
A* a = new B();
const A* b = new B();
cout << Register::getSize(a) << endl;
cout << Register::getSize(b) << endl;
}
Considering the nice answer of #Dennis Zickefoose, there's a case where you can implement multiple levels of inheritance which requires you neither to have virtual functions nor an intermediate class between each layer of inheritance and the added complexity.
And that's when all the intermediate (non-leaf) classes in the inheritance hierarchy are abstract classes, that is, they are not instantiated.
If that's the case, you can write the non-leaf abstract classes templated (again) on derived concrete types.
The example below demonstrates this:
template <class TDerived>
class Shape // Base
{
public:
float centerX;
float centerY;
int getSize()
{ return sizeof(TDerived); }
void demo()
{
std::cout
<< static_cast<TDerived*>(this)->getSize()
<< std::endl;
}
};
class Circle : public Shape<Circle>
{
public:
float radius;
};
class Square : public Shape<Square>
{
// other data...
};
template <class TDerived>
class Shape3D : public Shape<TDerived>
// Note that this class provides the underlying class the template argument
// it receives itself, and note that Shape3D is (at least conceptually)
// abstract because we can't directly instantiate it without providing it
// the concrete type we want, and because we shouldn't.
{
public:
float centerZ;
};
class Cube : public Shape3D<Cube>
{
// other data...
};
class Polyhedron : public Shape3D<Polyhedron>
{
public:
typedef float Point3D[3];
int numPoints;
Point3D points[MAX_POINTS];
int getSize() // override the polymorphic function
{ return sizeof(numPoints) + numPoints * sizeof(Point3D); }
// This is for demonstration only. In real cases, care must be taken about memory alignment issues to correctly determine the size of Polyhedron.
};
Sample usage:
Circle c;
c.demo();
Polyhedron p;
p.numPoints = 4;
p.demo();

class containing a generic type of a child

Is there any possible way that a generic type can be used to contain a child of a base class.
From the assignment given to me, I am to create something similar to the following in structure.
template <class T>
class Fruit {
private:
int count;
int location_id;
T type;
public:
virtual void displayInfo();
};
class Apple : private Fruit<Apple> {
private:
int variety;
public:
void displayInfo() {
printf("Location %i has %i of %s in stock", location_id, count, variety);
}
};
Fruit<Apple> appleinventory[SIZE];
Basically, I think you can't have a template generic type be the same as a derived class. Am I wrong? Is there something similar that would possibly work?
Update:
For the assignment, I believe we are to use inheritance to show use of virtual functions. I've updated the code above. I think this would work, but does NOT need templates to be successful. We have not covered any advanced, redundant inheritance methods in class.
This is perfectly fine, in principle.
Read up about Curiously Recurring Template Pattern (CRTP) for more info on usage of derived class as the instantiating type in a class template that is its base, esp the example about static polymorphism which should look 'curiously' familiar.
template <class Derived> struct Base
{
void interface()
{
// ...
static_cast<Derived*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
Derived::static_sub_func();
// ...
}
};
struct Derived : Base<Derived>
{
void implementation();
static void static_sub_func();
};
Ignoring questions of why you want to do this....you can get some of the way by doing this following:
template <class T> class Fruit
{
private:
int count;
int location_id;
T* type;
};
class Apple : private Fruit<Apple>
{
private:
int seeds;
bool red;
};
Fruit<Apple> appleinventory[SIZE];
Note the T* type is now a pointer to Apple rather than an instance of Apple.