As part of my template specification, i need to specialize another template - c++

As part of my RTOSQueue implementation,
template<typename T,uint32_t number_of_elements>
class RTOSQueue : public RTOSQueueBase, public RTOSQueueInterlocutor<T>
{
...
};
I need to specialize some helper functions based on the type that's held in the queue:
template<typename T>
class RTOSQueueInterlocutor
{
public:
void AfterSuccessfulSend(T&message) {};
void AfterSuccessfulReceive(T&message) {};
};
The idea is some classes need a little help going in or going out, one of which is a reference counted buffer template:
template<typename T,
#ifdef RTOS_HEADER_INCLUDED
typename Atomifier=RTOSCriticalSection
#else
typename Atomifier=int32_t
#endif
>
class shared_buffer : public buffer_interface<T>
{
T* m_pPtr;
size_t m_uElements;
int* count;
...
};
(Pardon the Atomifier. It's there's for thread safety if you're using it with an RTOS)
In order to specialize this, I put this in my code:
template<>
void RTOSQueueInterlocutor<shared_buffer<MyBuffer>>::AfterSuccessfulSend(shared_buffer<MyBuffer>&message)
{
message.increment();
}
Then when I declare an RTOSQueue<shared_buffer> it all works fine and the Interlocutor increments the reference count upon a succesful send so it 'stays alive' inside the queue.
I'd LIKE to make this RTOSQueueInterlocutor specialization be "automatic", which would mean whenever I declare a shared_buffer<> object, it should also declare the RTOSQueueInterlocutor<> as well.
Is this possible? My attempts at putting it in the header file were unsuccesfull.
I tried putting:
#ifdef RTOS_HEADER_INCLUDED
template<typename T>
void RTOSQueueInterlocutor<shared_buffer<T>>::AfterSuccessfulSend(shared_buffer<T>&message)
{
message.increment();
}
#endif
Below my definition of shared_buffer<> template, and it didn't like that at all.

Related

Use a derived class type as parameter of a base method in C++

I have the following classes in the following files:
// Tensor.hh
template <class T>
class Tensor {
/* declarations */
}
// Tensor.cpp
#include "Tensor.hh"
// Implementation of Tensor.hh
// Kernel.hh
#include "Tensor.hh"
template <class T>
class Kernel : public Tensor<T> {
/* declarations */
}
// Kernel.cpp
#include "Kernel.hh"
// Implementation of Kernel.hh
Is it possible to use a pointer to "Kernel" as parameter of a "Tensor" method?
Something like:
template <class T>
void Tensor<T>::foo(Kernel<T>* kernel) {
// Do something...
}
Yes it is possible. In your Tensor.cpp you will have to include #include "Kernel.hh", and in your Tensor.hh you will have to add a forward declaration:
template<typename>
class Kernel;
Usually I would really avoid forward declaring template classes, and I would avoid circular dependencies. Sometimes they are not avoidable, but sometimes yes.
Another solution would be to simply implement foo as a free function in another header:
void foo(Tensor<T>& tensor, Kernel<T>* kernel) {
// ...
}
That way you break the circular dependency, and you get bonus encapsulation.
I think you need to use forward declaration of the class Kernel. I could compile following:
template <class T>
class Kernel;
template <class T>
class Tensor {
/* declarations */
void foo(Kernel<T>* kernel);
};
template <class T>
class Kernel: public Tensor<T> {
};
The implementation of your class templates needs to be visible to your users. So it's best to put the implementation directly in the header file.
// Forward declare Kernel<T> so Tensor<T> can know about it for foo()
template<typename T>
class Kernel;
// Define Tensor<T>
template<typename T>
class Tensor {
void foo(Kernel<T>* kernel);
...
};
// Define Kernel<T>
template<typename T>
class Kernel : public Tensor<T> {
...
};
// Define Tensor<T>::foo here since Kernel<T> needs to be defined
// for it to do anything meaningful with it
template<typename T>
void Tensor<T>::foo(Kernel<T> *kernel) {
// Do something...
}

C++ How to extend a template to work with vector<T>

unfortunately my actual template is too full of stuff that is unrelated to my question, so i tried to put everything in a short example. Lets say, I have written the following template:
#include <vector>
template <typename T> class MyTemplate{
public:
typedef void(*MyFunc)(T);
void addFunc(MyFunc f){myFuncs.push_back(f);}
void callFuncs(T value){
for (std::size_t i=0;i<myFuncs.size();i++){myFuncs[i](value);}
}
private:
std::vector<MyFunc> myFuncs;
};
I learned already, that I can specialize this template to behave different when the passed type is a vector, so I wrote this:
template <typename T> class MyTemplate<std::vector<T> > {
public:
typedef void(*MySingleElementFunc)(T);
void addSingleElementFunc(MySingleElementFunc f){
this->mySingleElementFuncs.push_back(f);
}
void callFuncs(std::vector<T> value){
//for (std::size_t i=0;i<myFuncs.size();i++){
// myFuncs[i](value);
//}
for (std::size_t i=0;i<mySingleElementFuncs.size();i++){
for (int size_t i=0;i<value.size();i++){
mySingleElemetnFuncs[i](value[i]);
}
}
}
private:
std::vector<MySingleElementFunc> mySingleElementFuncs;
};
Now my question is, what is the most elegant way (if possible without inheritance) not only to specialize the template for the case of vector< T > but at the same time still being able to use the first templates methods where vector< T > is the template parameter. What I would like to do later is the following
void Func1(int i){}
void Func2(std::vector<int> i){}
MyTemplate<std::vector<int> > myTemplate;
myTemplate.addFunc(Func1);
myTemplate.addFunc(Func2);
Is it possible to achieve this without simply copy&paste all stuff I need from the original template, to do the same also with the specialized version? I guess I will have to use some kind of inheritance. However, I want to avoid something like this:
MyTemplate<std::vector<int> > myTemplate;
// myTemplate.addFunc(Func1); // does not work
myTemplate.addFunc(Func2);
MyVectorTemplate<std::vector<int> > myVectorTemplate;
myVectorTemplate.addFunc(Func1); // works
myVectorTemplate.addFunc(Func2);
i.e. the functionality should be determined only by the type passed to the template but not by choosing the appropriate subclass. Anyhow, I have to admit that I am a bit confused about how to inherit in this case. If it was not a template, I could write something like
class MyVectorClass : public MySingleObjectClass {}
However, the following does not make any sense:
template <typename T> MyTemplate<std::vector<T> > : public MyTemplate<std::vector<T> >
but in some sense, this is what I would like to have.
I am sorry for such a long post and I hope it is more or less clear what is my problem...
EDIT: I just found a mistake in the above code. The loop in the vector template should read
for (std::size_t i=0;i<mySingleElementFuncs.size();i++){
for (int size_t j=0;j<value.size();j++){
mySingleElemetnFuncs[i](value[j]);
}
}
i.e. each registered function should be called once for each entry in the vector. (Otherwise the template does not work if the number of registered functions is not equal to the size of the vector.)
In fact you want add functionality to the specialization, something like:
template <typename T> class MyTemplate<std::vector<T> >
{
public:
typedef void(*MySingleElementFunc)(T);
typedef void(*MyVectorFunc)(std::vector<T>);
void addSingleElementFunc(MyVectorFuncf){
this->myVcetorFuncs.push_back(f);
}
void addSingleElementFunc(MySingleElementFunc f){
this->mySingleElementFuncs.push_back(f);
}
void callFuncs(const std::vector<T>& value){
for (std::size_t i=0;i<myVectorFuncs.size();i++){
myVectorFuncs[i](value);
}
for (std::size_t i=0;i<mySingleElementFuncs.size();i++){
for (int size_t i=0;i<value.size();i++){
mySingleElemetnFuncs[i](value[i]);
}
}
}
private:
std::vector<MySingleElementFunc> mySingleElementFuncs;
std::vector<MyVectorFunc> myVectorFuncs;
};
template <typename T>
class MyTemplateBase {
// generic stuff goes here
};
template <typename T>
class MyTemplate : public MyTemplateBase<T> {
// nothing goes here
};
template <typename T>
class MyTemplate<std::vector<T>> : public MyTemplateBase <std::vector<T>> {
// specialized stuff goes here
}
If you don't want public inheritance you can use private inheritance, but then you would have to explicitly export everything inherited privately:
template <typename T>
class MyTemplate<std::vector<T>> : private MyTemplateBase <std::vector<T>> {
public:
// generic stuff re-exported
using MyTemplateBase<std::vector<T>>::Func1;
using MyTemplateBase<std::vector<T>>::Func2;
// specialized stuff goes here
}
Might still be worth it, as public inheritance is not exactly the most appropriate tool for code reuse.
I think that, since Vector is a template not a class, should be something like:
template<template <typename ...> class T /*= std::vector*/>
class SomeClass
{
T x;
};

Preprocessor magic to complete typename in template

I have a bunch of user-defined structs; let's call them A, B and C.
I can't modify them and I need to add logging capabilities; so I've added my own log versions of these structures to help with that.
Let's call them A_Log, B_Log and C_Log.
I'm creating a template StateLogger class with a member function called LogState(const T *ptr) where T is intended to be A, B or C.
template <typename T>
class StateLogger {
public:
void LogState(const T *ptr);
private:
std::vector<T> requests;
};
In this function, I intend to construct the A_Log/B_Log/C_Log structure.
template<typename T>
void StateLogger<T>::LogState(const T *ptr) {
...
VOODOO myLog = VOODOO(ptr);
}
I'm wondering if I can use some preprocessor magic to append _Log to T in VOODOO.
So, if I used StateLogger<A>::LogState(a_ptr)
I'd like the compiler to generate A_Log instead of Voodoo.
I realize I can use template specialization to get around this, but I was curious about this.
template <class T> struct logger_type;
template <> struct logger_type<A> {
typedef A_Log type;
};
etc.
With that, whenever you need the logger, just use typename logger_type<T>::type.

How to count the number of CRTP subclasses of a template class?

Does anyone know of a method to use CRTP to count the number of subclasses of an object?
Suppose we had a setup similar to the following one:
template <typename T>
class Object
{
....
};
const unsigned int ObjectSubClassCount = ...;
class Subobject : public Object<SubObject>
{
....
};
class Second : public Object<Second>
{
....
};
and so on, such that, using TMP, we might have a constant (ObjectSubClassCount) that represents the total number of subclasses?
Does anyone know a way to do this?
Edit: I am wanting to use the result as a template parameter later on, so I need it to be done with TMP...
Without the requirement to use the result as a template parameter later I would try it doing like this:
// Class which increments a given counter at instanciation
struct Increment {
Increment(std::size_t& counter)
{
counter++;
}
};
// This is your template base
template <typename T>
class Object
{
private:
// For every instanciation of the template (which is done for a subclass)
// the class counter should get incremented
static Increment incrementCounter;
};
// This is the global object counter
static std::size_t classCounter;
// Static Member Variable
template<typename T>
Object<T>::incrementCounter(classCounter);
Haven't tried it but should do. To have the result available as a template parameter again (MPL) I don't have enough experience in MPL but I doubt this is possible.
Ok, so I've come upon a... somewhat acceptable answer.
I figured that it would not work out if the subclasses had absolutely not knowledge of eachother (I mean, we're talking somewhat functional programming...).
Here's a solution for this. It's definitely not the solution I'd wish for; however, it is a start. I've forced all objects to use a form of CRTP, but one that uses more of a linked list format. In this way, our subclasses must be derived from an Object<> templated from:
A: itself
and B: the most recent previously defined subclass
here is my code for this (I use a template from <type_traits> once, just a note)
template <typename T> //SFINAE check for the existance of subclasscount static member
struct has_subclasscount
{
template <typename U>
static typename std::enable_if<sizeof(U::subclasscount) != 0, int>::type test(int);
template <typename U>
static char test(...);
static const bool result = (sizeof(test<T>(0)) == sizeof(int))?(true):(false);
};
template <bool res, typename T>
struct return_subclasscount //the value to return is 0 if false
{
static const int result = 0;
};
template <typename T>
struct return_subclasscount<true, T> //returns subclasscount only if the first parameter is true
{
static const int result = T::subclasscount;
};
template <typename T> //combines return_subclasscount and has_subclasscount
struct get_subclasscount
{
static const int result = return_subclasscount<has_subclasscount<T>::result, T>::result;
};
template <typename This, typename Prev>
class Object
{
public:
static const int subclasscount = 1 + get_subclasscount<Prev>::result; //the subclass count
};
class sub1 : public Object<sub1, int>
{
};
class sub2 : public Object<sub2, sub1>
{
};
class sub3 : public Object<sub3, sub2>
{
};
These last 3 empty classes are the subclasses that we're counting. This is our header file.
In our main .cpp file, we have:
int main() {
std::cout << sub3::subclasscount;
char c;
std::cin >> c;
}
Running it, we get a simple output of:
3
Which confirms that it has worked.
Now, some of the downsides to this solution is:
We must know what our last defined subclass was, before we add on.
We must keep up with anywhere we use the subclass counter, always modifying it to be from the last subclass in the list (this can be averted by using a consistant "endoflist" subclass, which would need to be maintained instead)
Upsides, though, include the fact that we do not need to upkeep any of our previously defined subclasses. However, I consider this answer more of a "starting point" than a "final solution"; perhaps something that can be expanded upon?
(also, this can easily be abused to make a form of tree structure, where subclasscount would actually represent the depth of any given node in the tree)
Anyone have any ideas from here?

Using child class as a template parameter of a base class and as a nested name specifier

I'm using my class as a template parameter of one of its parent class, and that parent class uses it in a template argument (though sizeof()).
And the compiler gives me:
error : incomplete type 'Invoker::workerClass {aka MyClass}' used in nested name specifier
Yet the class is well defined in the file. I guess this is because the child class isn't instantiated at the moment of the base class' instantiation, yet that kind of thing happens with CRTP and there's no problems.
The reason I use the child class in the template argument is to do a different function call if the child class has, or doesn't have, a specific function.
Here's a minimal code for testing
/* Structure similar to boost's enable if, to use
SFINAE */
template <int X=0, class U = void>
struct test {
typedef U type;
};
enum Commands {
Swim,
Fly
};
/* Structure used for template overloading,
as no partial function template specialization available */
template<Commands T>
struct Param {
};
template <class T>
class Invoker
{
public:
typedef T workerClass;
workerClass *wc() {
return static_cast<workerClass*>(this);
}
template <Commands command>
void invoke() {
invoke2(Param<command>());
}
/* If the child class has those functions, call them */
/* Needs template paramter Y to apply SFINAE */
template<class Y=int>
typename test<sizeof(Y)+sizeof(decltype(&workerClass::fly))>::type
invoke2(Param<Fly>) {
wc()->fly();
}
template<class Y=int>
typename test<sizeof(Y)+sizeof(decltype(&workerClass::swim))>::type
invoke2(Param<Swim>) {
wc()->shoot();
}
template<Commands command>
void invoke2(Param<command>) {
/* Default action */
printf("Default handler for command %d\n", command);
}
};
template <class T, class Inv = Invoker<T> >
class BaseClass : public Inv
{
public:
template<Commands command>
void invoke() {
Inv::template invoke<command>();
}
};
class MyClass : public BaseClass<MyClass>
{
public:
void swim() {
printf("Swimming like a fish!\n");
}
/* void fly(); */
};
void testing() {
MyClass foo;
foo.invoke<Fly>(); /* No 'void fly()' in MyClass, calls the default handler */
foo.invoke<Swim>(); /* Should print the swimming message */
}
The error happens at the line:
typename test<sizeof(Y)+sizeof(decltype(&workerClass::fly))>::type
So, is there any compiler that supports this, or is this explicitely specified by the standard as an invalid use of templates? Do I have to change the way I'm doing this and find a way around? CRTP is giving me hope the code might be valid, but I'm not sure.
If this really isn't possible, then why exactly, and why does CRTP work?
The solution was, as ildjarn pointed out, to add another level of indirection.
That is done by changing the test function to accept types:
template <typename X, class U = void>
struct test {
typedef U type;
};
And then pass the child class as a template parameter, instead of specifying it from the get go:
template<class Y=workerClass>
typename test<decltype(&Y::fly)>::type
invoke2(Param<Fly>) {
wc()->fly();
}
template<class Y=workerClass>
typename test<decltype(&Y::swim)>::type
invoke2(Param<Swim>) {
wc()->swim();
}
That way the nested specifier is evaluated only when the function is called and not at the class evaluation, and by that time the child class is already evaluated. Plus with the possibility to pass default template argument, we can call the function without any template parameters.
The template is also much more readable now. And the sample code works just fine now:
class MyClass : public BaseClass<MyClass>
{
public:
void swim() {
printf("Swimming like a fish!\n");
}
/* void fly(); */
};
void testing() {
MyClass foo;
foo.invoke<Fly>(); /* No 'void fly()' in MyClass, calls the default handler */
foo.invoke<Swim>(); /* Should print the swimming message */
}