Mixin layers & static binding - c++

I'm currently playing with mixin layers designs, and I'm stuck with an
annoying problem.
Let's consider the following basic mixin layer:
template <typename Next>
struct Layer1 : public Next
{
struct A : public Next::A
{
void f() { g(); }
void g() {}
};
};
Nothing fancy here, just a simple mixin with 2 methods f() and g().
Notice that the g() call from f() is is statically binded to this
specific Layer1::A::g().
Now, what I want is to be able to completely hook the methods of this
mixin to implement, say, a logging layer:
template <typename Next>
struct Layer2 : public Next
{
struct A : public Next::A
{
void f()
{
std::cout << "Layer2::A::f() [enter]" << std::endl;
Next::A::f();
std::cout << "Layer2::A::f() [leave]" << std::endl;
}
void g()
{
std::cout << "Layer2::A::g() [enter]" << std::endl;
Next::A::g();
std::cout << "Layer2::A::g() [leave]" << std::endl;
}
};
};
Considering Layer2<Layer1<...>>, the problem here is that any call of
f() and g() from a layer above Layer2 will properly cascade down to
the Layer2::A::g(), and thus display the proper logging messages. But
any call of f() and g() from below Layer2 will not log anything since
the call would have been statically binded to the g() available at the
time the call was made.
This means that calling f() from any layer above Layer2 will obviously
still always call Layer1::A::g() from Layer1::A::f() and not display
the logging messages.
I came up with 2 solutions to this problem:
Virtuality: clearly not acceptable. The whole point of mixin layers
is to avoid virtuality when not necessary.
Adding a template parameter to the layers to provide the previous
layer, something of the kind.
.
template <typename Next, template <typename> class Prev>
struct Layer2 : public Next
{
typedef Next next_t;
struct A : public Next::A
{
void f()
{
std::cout << "Layer2::A::f() [enter]" << std::endl;
Next::A::f();
std::cout << "Layer2::A::f() [leave]" << std::endl;
}
void g()
{
std::cout << "Layer2::A::g() [enter]" << std::endl;
Next::A::g();
std::cout << "Layer2::A::g() [leave]" << std::endl;
}
};
};
template <typename Next, template <typename> class Prev>
struct Layer1 : public Next
{
typedef Next next_t;
struct A : public Next::A
{
void f()
{
std::cout << "Layer1::A::f() [enter]" << std::endl;
((typename Prev<Layer1<Next,Prev> >::A*)this)->g();
std::cout << "Layer1::A::f() [leave]" << std::endl;
}
void g()
{
std::cout << "Layer1::A::g() [enter]" << std::endl;
std::cout << "Layer1::A::g() [leave]" << std::endl;
}
};
};
typedef Layer2<Layer1<Layer0,Layer2>,NullType> Application;
Well, it works, but I would like to hide this second template
parameter since it is redundant.
I wondered if any of you ever encountered such problem, and what
solutions did you developped to solve it, since there is a clear lack
of articles on mixin layers.

Related

Template specialization by argument instead by type

Is it possible to specialize a template class by argument instead by type?
The target is to have a comfortable interface and as less as possible execution time.
At the moment I know three options with different benefits.
One Class with different beaviour depending on CTor Parameter
Define different classes
Specialized template classes
The first possibility does not fit the execution time requirement.
The second possibility does not have a nice interface, because everybody has to know that there are multiple classes with just slighly different behaviour.
The third solution is my favorit, but therefore it is needed to declare types as switches.
So I am looking for a mixture between 1. and 3.
I may be missing the correct keywords to search with.
Here the possibilities I know so far:
#include <iostream>
/**
* opt1 -- switch at runtime
*/
class inoutslow
{
public:
inoutslow(bool b): _switch(b)
{
if(_switch)
std::cout << "slowIn1" << std::endl;
else
std::cout << "slowIn2" << std::endl;
}
~inoutslow()
{
if(_switch)
std::cout << "slowOut1" << std::endl;
else
std::cout << "slowOut2" << std::endl;
}
private:
bool _switch;
};
/**
* opt2 -- different self defined classes
*/
class inout1
{
public:
inout1(){std::cout << "in1" << std::endl;}
~inout1(){std::cout << "out1" << std::endl;}
};
class inout2
{
public:
inout2(){std::cout << "in2" << std::endl;}
~inout2(){std::cout << "out2" << std::endl;}
};
/**
* opt3 -- specialized template
*/
struct trueType;
struct falseType;
template<typename T>
class inout
{
public:
inout(){std::cout << "DefaultTin" << std::endl;}
~inout(){std::cout << "DefaultTout" << std::endl;}
};
template <>
class inout<trueType>
{
public:
inout(){std::cout << "Tin1" << std::endl;}
~inout(){std::cout << "Tout1" << std::endl;}
};
template <>
class inout<falseType>
{
public:
inout(){std::cout << "Tin2" << std::endl;}
~inout(){std::cout << "Tout2" << std::endl;}
};
int main()
{
inoutslow i(true);
inoutslow j(false);
inout1 ii;
inout2 jj;
inout<trueType> iii;
inout<falseType> jjj;
}
the above code in coliru
Thank you guys -- for all those who might find this question instead of Using template instead of switch
/**
* opt 4
*/
template<bool _switch>
class inoutT;
template <>
class inoutT<true>
{
public:
inoutT(){std::cout << "TTin1" << std::endl;}
~inoutT(){std::cout << "TTout1" << std::endl;}
};
template <>
class inoutT<false>
{
public:
inoutT(){std::cout << "TTin2" << std::endl;}
~inoutT(){std::cout << "TTout2" << std::endl;}
};
working sample of all (listed) possibilities

Runtime type deduction and code duplication

I have some types defined by the values of an enumerator, which represent the type of data read in from a file. I wish to do a different processing workflow based on the type of data , but it results in a lot of code duplication:
#include <iostream>
enum dataType {
type1,
type2,
type3
};
struct File {
File(dataType type):type{type}{};
dataType type;
};
void process_file(File file)
{
if(file.type == dataType::type1){ std::cout << "Do work A" << std::endl; };
if(file.type == dataType::type2){ std::cout << "Do work B" << std::endl; };
if(file.type == dataType::type3){ std::cout << "Do work C" << std::endl; };
}
int main(){
File file(dataType::type2);
process_file(file);
return 0;
}
My main problem is with having to check the value via "if" or a switch statement. Imagine there being 50 types instead of just 3 and it becomes quite a chore and error prone to check every single one.
Does anyone know of a way to deal with this? Template code is the obvious thing to try but I'm stuck using the enumerator to determine the type, so I didn't think template code was possible here, at least the attempts I've made have not been successful.
A typical way to get rid of switch is inheritance and virtual function:
struct File {
virtual ~File() = default;
virtual void process() = 0;
};
struct Type1File : public File {
void process() override { std::cout << "Do work A" << std::endl; };
};
struct Type2File : public File {
void process() override { std::cout << "Do work B" << std::endl; };
};
int main(){
std::unique_ptr<File> file = std::make_unique<Type1File>();
file->process();
return 0;
}
How about injecting a SomeWorker object into the file class instead of having a type data member?
class SomeWorker
{
...
public:
virtual void DoWork() = 0;
};
class SomeWorker1 : public SomeWorker
{
...
public:
void DoWork() override { std::cout << "Do work A" << std::endl;}
};
class SomeWorker2 : public SomeWorker
{
...
public:
void DoWork() override { std::cout << "Do work B" << std::endl;}
};
...
struct File {
File(SomeWorker worker):someWorker{worker}{};
SomeWorker someWorker;
};
int main(){
SomeWorker2 someWorker;
File file(someWorker);
file.someWorker.DoWork();
return 0;
}
Obviously, the code is not complete and there are virtual destructors to add and things to improve, but you get the idea...
You can do it passing the dataType as a template parameter.
#include <iostream>
enum class dataType {
type1,
type2,
type3
};
template <dataType T>
struct File {};
void process_file(File<dataType::type1> file) {
std::cout << "Do work A" << std::endl;
}
void process_file(File<dataType::type2> file) {
std::cout << "Do work B" << std::endl;
}
void process_file(File<dataType::type3> file) {
std::cout << "Do work C" << std::endl;
}
int main() {
File<dataType::type1> file1;
File<dataType::type2> file2;
File<dataType::type3> file3;
process_file(file1);
process_file(file2);
process_file(file3);
return 0;
}
However you then also need to accommodate the fact that File is a template, so passing it to other functions ect. is not as easy anymore. You can either change all functions dealing with File to a template aswell, or give all the File variations a common base class.
The other answers seem easier and more to the point in this case to me. Mostly posted this since you mentioned it in your question.

c++ decorator pattern, static polymorphism with templates and registering callback methods

I am attempting to use static polymorphism to create a decorator pattern.
As to why I do not use dynamic polymorphism, please see this QA. Basically, I could not dynamic_cast to each decorator so as to access some specific functionality present only in the decorators (and not in the base class A).
With static polymorphism this problem has been overcome, but now I cannot register all the et() methods from the decorators back to the base class A (as callbacks or otherwise), thus when A::et() gets called, only A::et() and Z::et() get executed. I want all of A,X,Y,Z ::et() to be executed (the order for X,Y,Z does not matter).
How can I do that using the following structure?
I can see in wikipedia that CRTP should allow you to access member of a derived class using static_cast, but how do you approach the problem when there are multiple derived template classes?
If this is not possible with static polymorphism but it is possible with dynamic polymorphism could you reply to the other question?
struct I {
virtual void et() = 0;
};
class A : public I {
public:
A() {
cout << "A::ctor " ;
decList.clear();
}
void regDecorator(I * decorator)
{
if (decorator) {
cout << "reg= " << decorator << " ";
decList.push_back(decorator);
}
else
cout << "dec is null!" <<endl;
}
virtual void et()
{
cout << "A::et ";
cout << "declist size= " << decList.size() << endl;
list<I*>::iterator it;
for( it=decList.begin(); it != decList.end(); it++ )
static_cast<I *>(*it)->et();
}
std::list<I*> decList; //FIXME
};
template<typename Base>
class X: public Base {
public:
X(){
cout << "X::ctor ";
Base::regDecorator(this);
}
virtual void et(){
cout << "X::et" <<endl;
}
};
template<typename Base>
class Y: public Base {//public D {
public:
Y(){
cout << "Y::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Y::et" <<endl;
}
};
template<typename Base>
class Z: public Base {//public D {
public:
Z() {
cout << "Z::ctor ";
Base::regDecorator(this);
}
void et(){
cout << "Z::et" <<endl;
}
};
int main(void) {
Z<Y<X<A> > > mlka;
cout << endl;
mlka.et();
return 0;
}
This structure is to be used as a reference for data acquisition from a set of sensors. class A is the base class and contains common functionality of all the sensors. This includes:
- data container (f.e. `boost::circular_buffer`) to hold an amount of timestamped sample data acquired from the sensor.
- a Timer used to measure some timed quantities related to the sensors.
- other common data and calculation methods (fe. `calculateMean()`, `calculateStdDeviation()`)
In fact the A::timer will call A::et() on completion in order to perform some statistical calculations on the sampled data.
Similarly, X,Y,Z are types of sensor objects each with responsibility to extract different type of information from the sampled data. and X,Y,Z::et() perform a different type of statistical calculation on the data. The aim is perform this calculation as soon as the A::Timer waiting time elapses. This is why I want to have access to all of X,Y,Z::et() from A::et(). Is it possible without affecting the static polymorphism shown in the example?
Thank you
You started using mixins, so use them to the end.
It follows a minimal, working example:
#include<iostream>
struct I {
virtual void et() = 0;
};
template<typename... T>
struct S: I, private T... {
S(): T{}... {}
void et() override {
int arr[] = { (T::et(), 0)..., 0 };
(void)arr;
std::cout << "S" << std::endl;
}
};
struct A {
void et() {
std::cout << "A" << std::endl;
}
};
struct B {
void et() {
std::cout << "B" << std::endl;
}
};
int main() {
I *ptr = new S<A,B>{};
ptr->et();
delete ptr;
}
As in the original code, there is an interface I that offers the virtual methods to be called.
S implements that interface and erases a bunch of types passed as a parameter pack.
Whenever you invoke et on a specialization of S, it invokes the same method on each type used to specialize it.
I guess the example is quite clear and can serve as a good base for the final code.
If I've understood correctly the real problem, this could be a suitable design for your classes.
EDIT
I'm trying to reply to some comments to this answer that ask for more details.
A specialization of S is all the (sub)objects with which it is built.
In the example above, S<A, B> is both an A and a B.
This means that S can extend one or more classes to provide common data and can be used as in the following example to push around those data and the other subobjects:
#include<iostream>
struct I {
virtual void et() = 0;
};
struct Data {
int foo;
double bar;
};
template<typename... T>
struct S: I, Data, private T... {
S(): Data{}, T{}... {}
void et() override {
int arr[] = { (T::et(*this), 0)..., 0 };
(void)arr;
std::cout << "S" << std::endl;
}
};
struct A {
void et(Data &) {
std::cout << "A" << std::endl;
}
};
struct B {
void et(A &) {
std::cout << "B" << std::endl;
}
};
int main() {
I *ptr = new S<A,B>{};
ptr->et();
delete ptr;
}

Conditional member function execution

Suppose you have a class Foo with a function Foo::bar().
Surrounding this function is a Monitor<Foo> class, which wrapps around Foo and forwards any function call by overloading operator->.
Further, the Monitor class has a boolean flag execute. If execute is true, all function calls
of Foo should be executed normally, but if execute is set to false, execution should be skipped.
The following snippet shows how this could look like:
#include <iostream>
using namespace std;
class Foo {
void bar() {std::cout << "Foo::bar()";}
};
template<typename T> class Monitor<T> {
T& ref;
bool exec;
public:
Monitor(T& obj) : ref(obj), exec(true) {}
T* operator->() {/* if exec */ return &ref;}
void setExec(bool e) {exec = e;}
};
int main() {
Foo foo;
Monitor<Foo> monitor(foo);
monitor->bar(); // call Foo::bar();
monitor.setExec(false);
monitor->bar(); // do nothing
}
Is this possible to implement? The obvious solution is to have a Base class IFoo, and
a Mock implementation MockFoo doing nothing, and then return a pointer to a MockFoo object
when operator-> is called. This makes the whole thing rather inflexible however, as you have to
provide a Mock object for any class you want to monitor.
So, is there a better way to achieve this?
In case you know which function you are going to call, you could do something like the following. This even allows for specification of a default return value of the function in the case exec==false. I am sure I didn't consider all the possible traps of reference return arguments, const member functions, etc. But I am sure you can adapt it if you want to use it.
#include <iostream>
struct X {
double callX(const int& x){ return x/100.;};
};
struct Y {
int callY(const std::string& y){ return y.length();};
};
template<typename F> class Monitor;
template<typename T, typename Ret, typename ...Args>
class Monitor<Ret(T::*)(Args...)> {
T& ref;
Ret(T::*func)(Args...);
Ret defaultRet;
bool exec;
public:
Monitor(T& ref, Ret(T::*func)(Args...), Ret defaultRet = Ret())
: ref(ref),
func(func),
defaultRet(defaultRet),
exec(true){};
void setExec(bool e) {exec = e;};
Ret call(Args&&... args) {
if(exec)
return (ref.*func)(std::forward<Args>(args)...);
else
return defaultRet;
};
};
template<typename T, typename Ret, typename ...Args>
auto makeMonitor(T& x, Ret(T::*f)(Args...), Ret r = Ret()) {
return Monitor<Ret(T::*)(Args...)>(x,f,r);
}
int main() {
X x;
Y y;
auto xmon = makeMonitor(x, &X::callX);
auto ymon = makeMonitor(y, &Y::callY);
auto ymon_def = makeMonitor(y, &Y::callY, 123);
std::cout << "callX(3)=" << xmon.call(3) << std::endl;
std::cout << "callY(\"hello\")=" << ymon.call("hello") << std::endl;
std::cout << "[default return] callY(\"hello\")=" << ymon_def.call("hello") << std::endl;
xmon.setExec(false);
ymon.setExec(false);
ymon_def.setExec(false);
std::cout << "After setExec(false):" << std::endl;
std::cout << "callX(3)=" << xmon.call(3) << std::endl;
std::cout << "callY(\"hello\")=" << ymon.call("hello") << std::endl;
std::cout << "[default return] callY(\"hello\")=" << ymon_def.call("hello") << std::endl;
return 0;
}
Output is:
callX(3)=0.03
callY("hello")=5
[default return] callY("hello")=5
After setExec(false):
callX(3)=0
callY("hello")=0
[default return] callY("hello")=123
Working example is here.
The "obvious" solution you mentioned can be streamlined a little, so you only have to define one additional (mock) class and no additional base classes. If you don't mind the slight performance loss due to virtual member functions, you can go about it like this:
#include <iostream>
struct MockX;
struct X {
typedef MockX mock;
virtual double doX(int x){ return x/100.;};
};
struct MockX : X {
virtual double doX(int x){ return 0.;};
};
struct MockY;
struct Y {
typedef MockY mock;
virtual int doY(std::string y){ return y.length();};
};
struct MockY : Y {
virtual int doY(std::string y){ return 123;};
};
template <typename T>
struct Monitor {
T& ref;
static typename T::mock dummy;
bool exec;
Monitor(T& ref) : ref(ref), exec(true){};
void setExec(bool e){exec = e;};
T* operator->(){
if(exec)
return &ref;
else
return &dummy;
};
};
template<typename T>
typename T::mock Monitor<T>::dummy{};
int main() {
X x;
Y y;
auto xmon = Monitor<X>(x);
auto ymon = Monitor<Y>(y);
std::cout << "doX(3)=" << xmon->doX(3) << std::endl;
std::cout << "doY(\"hello\")=" << ymon->doY("hello") << std::endl;
xmon.setExec(false);
ymon.setExec(false);
std::cout << "After setExec(false):" << std::endl;
std::cout << "doX(3)=" << xmon->doX(3) << std::endl;
std::cout << "doY(\"hello\")=" << ymon->doY("hello") << std::endl;
return 0;
}
I made the dummy mock object static, so there will only be one copy for each type you're monitoring. Everything you need is a typedef in the real class specifying your mock class, and the mock class inheriting from the real class and overriding the (virtual) methods you want to disable when exec==false. You have to be aware though that even the methods you don't override will be called on the dummy object when exec==false, so they might not behave as expected.
However, this could also be an advantage: If you write X and Y in such a way that a default-constructed object (or one constructed with a special flag specified in the constructor) behaves like a mock class, you don't even need a mock-class (just construct dummy that way). But then you could almost build that "disabling" functionality into X itself and you don't need the monitor... ;-)

C++ - Smart Pointers - Casting smart pointers inside templates

I have a complex code base at work, and i created a small example to mimic the problem and here is the below code.
< Code below for reference> - This code is compilable if we have boost libraries and FastDelegate.h linked with the project. Please let me know if you need the full compilable example project, i can email you.
I have two problems and need help resolving them.
As seen below in the code, i have a class with argument type as template for another classes object. Now when i initialize the class below in UserClass's constructor (Line 107) i get error because mBaseAcceptor is a class with template argument of type base Class, but i need to do mbaseAcceptor(new derivedAcceptor_t). Casting problem how to fix this?
Error here is
./boost/smart_ptr/shared_ptr.hpp:387:9: error: comparison between distinct pointer types ‘Acceptor<DerivedClass>*’ and ‘Acceptor<BaseClass>*’ lacks a cast
Another problem is in line 108, even if i magically say resolve this by using another acceptor of derived class, this is where i use that mDerivedAcceptor, in Line 108 i do
mDerivedAcceptor->SetDelegate(fastdelegate::MakeDelegate(this, &UserClass::HandleDelegate));
then i get error saying
"error no matching function call for HandleDelegate(DerivedClass&, bool).
This make sense because HandleDelegate has argument of type BaseClass and by storing a delegate(which is a func. ptr) we have to call the function with appropriate argument. But how to fix this.
If i cast Handler inside Acceptor class with derived class will it work when i only pass the baseClass pointer?
Code
/*
* smart_pointer_1.cpp
*
* Created on: Jul 26, 2011
* Author: balaji
*/
#include <algorithm>
#include <boost/foreach.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include "FastDelegate.h"
#include <iostream>
using namespace std;
template <class Handler>
class Acceptor {
public:
typedef fastdelegate::FastDelegate1<Handler &, bool> delegate_t;
Acceptor ();
void Initialize(Handler *&handle);
void SetDelegate(delegate_t delegate) { mDelegate = delegate; }
private:
int mValues[2];
delegate_t mDelegate;
};
template <class Handler>
Acceptor<Handler>::Acceptor()
{
std::cout << "In Constructor: " << __FUNCTION__ << std::endl;
mValues[0] = 1;
mValues[1] = 2;
}
template <class Handler>
void Acceptor<Handler>::Initialize(Handler *&handle){
if (!handle) {
std::cout << __FUNCTION__ << " : created" << std::endl;
handle = new Handler();
} else {
std::cout << __FUNCTION__ << " : Error exception" << std::endl;
}
if (mDelegate && mDelegate(*handle)) {
std::cout << "Ok Called Handle in " << __FUNCTION__ << std::endl;
} else {
std::cout << "Not Called Handle in " << __FUNCTION__ << std::endl;
}
handle->displayComputer();
}
class BaseClass {
std::string mComputer;
public:
BaseClass() {
std::cout << "In Base Constructor: " << __FUNCTION__ << std::endl;
mComputer = "Mac";
}
virtual void displayComputer() {
std::cout << "Computer type is " << mComputer << std::endl;
}
};
class DerivedClass : public BaseClass {
std::string mLanguage;
public:
DerivedClass() {
std::cout << "In Derived Constructor: " << __FUNCTION__ << std::endl;
mLanguage = "C++";
}
void displayComputer() {
std::cout << "Language is " << mLanguage << std::endl;
}
};
class UserClass {
public:
UserClass();
UserClass(bool);
typedef Acceptor<BaseClass> baseAcceptor_t;
typedef Acceptor<DerivedClass> derivedAcceptor_t;
typedef boost::shared_ptr<BaseClass> basePtr_t;
void CallDelegate(BaseClass&);
private:
boost::shared_ptr<baseAcceptor_t> mBaseAcceptor;
boost::shared_ptr<derivedAcceptor_t> mDerivedAcceptor;
BaseClass *mConnBasePtr;
bool HandleDelegate(BaseClass& baseDelegate);
};
UserClass::UserClass() : mBaseAcceptor(new baseAcceptor_t)
{
std::cout << "In Constructor: " << __FUNCTION__ << std::endl;
mBaseAcceptor->SetDelegate(fastdelegate::MakeDelegate(this, &UserClass::HandleDelegate));
mBaseAcceptor->Initialize(mConnBasePtr);
}
UserClass::UserClass(bool value)
{
std::cout << "In Constructor: " << __FUNCTION__ << std::endl;
mBaseAcceptor.reset(new derivedAcceptor_t); // <<========== Problem Here because of improper casting
mBaseAcceptor->SetDelegate(fastdelegate::MakeDelegate(this, &UserClass::HandleDelegate)); // <<=== Also here because of improper type passed to MakeDelegate function ptr. Please note HandleDelegate has an argument of type BaseClass, but Acceptor is derived class
mBaseAcceptor->Initialize(mConnBasePtr);
}
bool UserClass::HandleDelegate(BaseClass& baseDelegate)
{
std::cout << "In " << __FUNCTION__ << std::endl;
return true;
}
int main() {
std::cout << "In function: " << __FUNCTION__ << std::endl;
typedef boost::shared_ptr<UserClass> userPtr_t;
userPtr_t user(new UserClass(true));
std::cout << "In function: " << __FUNCTION__ << " at end "<< std::endl;
return 0;
}
Acceptor<DerivedClass> is not derived from Acceptor<BaseClass> (it doesn't matter that DerivedClass is derived from BaseClass or not) so the compiler can not cast one into the other.
I would get rid of the templatization of the acceptor, unless you have a good reason to keep it (which I don't see in your code) :
class Acceptor {
public:
typedef fastdelegate::FastDelegate1<BaseClass &, bool> delegate_t;
Acceptor ();
void Initialize(BaseClass *handle);
void SetDelegate(delegate_t delegate) { mDelegate = delegate; }
private:
int mValues[2];
delegate_t mDelegate;
};
void Acceptor::Initialize(BaseClass *handle){
if (!handle) {
std::cout << __FUNCTION__ << " : Error exception" << std::endl;
}
if (mDelegate && mDelegate(*handle)) {
std::cout << "Ok Called Handle in " << __FUNCTION__ << std::endl;
} else {
std::cout << "Not Called Handle in " << __FUNCTION__ << std::endl;
}
handle->displayComputer();
}
Then you don't need separate baseAcceptor_t and derivedAcceptor_t types as they both become simply Acceptor, and you can do for example :
UserClass::UserClass() : mBaseAcceptor(new Acceptor(new BaseClass))
As far as I see the only thing you loose is the ability to pass a null pointer to the acceptor's constructor and have it create its handler itself. That's a very minor loss as the real decision (instantiate a base or a derived handler) is really taken when you instantiate the Acceptor anyway (because you choose which of Acceptor<BaseClass> or Acceptor<DerivedClass> you want)
Define base class for the Acceptor template and another class that will be base to all Handler types. So your implementation will change to:
class IHandler {
};
class IAcceptor {
public:
virtual void Initialize(IHandler *) = 0;
virtual void SetDelegate(delegate_t delegate) = 0;
};
Your Acceptor template will change to:
template <class Handler>
class Acceptor : public IAcceptor {
public:
typedef fastdelegate::FastDelegate1<Handler &, bool> delegate_t;
Acceptor ();
void Initialize(IHandler *pVal);
void SetDelegate(delegate_t delegate) { mDelegate = delegate; }
private:
int mValues[2];
delegate_t mDelegate;
};
Your implementation for Initialize will change (Make sure you handle the dynamic_cast result correctly):
template <class Handler>
void Acceptor<Handler>::Initialize(IHandler *pVal){
Handler *pHandle = dynamic_cast<Handler>(pVal); //You will have to ofcourse ttake appropriate action if this cast fails.
if (!handle) {
std::cout << __FUNCTION__ << " : created" << std::endl;
handle = new Handler();
} else {
std::cout << __FUNCTION__ << " : Error exception" << std::endl;
}
if (mDelegate && mDelegate(*handle)) {
std::cout << "Ok Called Handle in " << __FUNCTION__ << std::endl;
} else {
std::cout << "Not Called Handle in " << __FUNCTION__ << std::endl;
}
handle->displayComputer();
}
Finally all classes that have to be used with the Acceptor will have to be derived from IHandler.
Now you can change your pointer declaration to shared_ptr< IAcceptor >.
EDIT:
Based on your comment for the second issue, I would pass the Handler object as a pointer instead of a reference and modify the UserClass::HandleDelegate method to accept a pointer to the BaseClass (or the IHandler class if you want to be even more generic.).
You can try to use boost::static_pointer_cast, because even though
class Derived : public Base{};
it doesn't make boost::shared<Derived> inherit from boost::shared_ptr<Base>.
So you have to use explicit boost cast like boost::static_pointer_cast, boost::dynamic_pointer_cast accordingly.