C++ class template as property type - c++

I have a class template in a c++ project:
template<class RequestHandler = DefaultRequestHandler>
class Server { ... }
I then have another class in which I want to hold an instance of Server<WhateverRequestHandlerIWant> as a property. So currently I have something like:
class OtherClass {
public: Server<>* server;
};
Unless I am mistaken, this will only allow me to store Server classes in which the template parameter is the class DefaultRequestHandler, correct?
Is there a way to write this without just making OtherClass a class template as well?

You could add a common abstract class for all server-like classes:
class IServer { ... };
then
template<class RequestHandler = DefaultRequestHandler>
class Server : virtual public IServer { ... }
and
class OtherClass {
public: IServer* server;
};

Related

Extending a CRTP template functionality

I'm a bit new to templates so bear with me if I'm asking obvious questions.
Given the following class hierarchy:
template<typename T>
class Singleton_T
{
...
static T& getInstance(){ ... }
...
}
template<typename T>
class Pool_T: public Singleton_T<Pool_T<T> >
{
...
T* createObject();
...
}
Now I want a class that extends the Pool_T functionality while also being a Singleton_T.
So I want to have in the new class the methodsgetInstance defined in Singleton_T and createObject defined in Pool_T tailored to my new type.
The initial approach would be:
struct myStruct;
class Manager : public Pool_T<myStruct>
{
...
void loadObjectsFromFile();
...
}
However , this makes the GetInstance of the Singleton_T to instantiate and return Pool_T<myStruct> type, so the loadObjectsFromFile method won't be available via getInstance (an object of Manager type won't be created).
In order to solve this I made the following change in hierarchy :
template< typename TDerrived, typename T>
class Pool_T : public Singleton_T < TDerrived >
{
...
T* createObject();
...
}
class Manager : public Pool_T<Manager, myStruct>
{
...
loadObjectsFromFile();
...
}
Now I can use all the three methods: getInstance, createObject and loadObjectsFromFile.
However this forces Pool_T to no longer be possible to instantiate from only 1 type.
EG:
struct someStruct;
class StructPool : public Pool_T<someStruct>; // no longer possible
In order to "solve" this i defined another template:
template <typename T>
class AlonePool_T: public Pool_T<AlonePool_T<T>, T>
{
// empty class
// allows instantiation of what was previously Pool_T<someStruct>
}
Now I can use this where previously Pool_T<someStruct> was defined.
struct someStruct;
class StructPool : public AlonePool_T<someStruct>;
However this will result in allot of find and replace in code that I'm not owner off.
Is there any way to achieve the following:
maintain Pool_T original definition
create a class that extends the Pool_T functionality (adds the loadObjectsFromFile method)
the class has getInstance and createObject methods correctly implemented (the correct types are used)
EDIT:
Added three methods to better underline the desired effect.
Given's liliscent's answer I changed the hierarchy to better show what I'm after.
If I understand your question correctly, a typical CRTP implementation of your hierarchy is:
template<class T>
struct Singleton {};
template<class Derived, class T>
struct Pool
: public Singleton<Derived>
{};
struct MyStruct {};
struct Manager
: public Pool<Manager, MyStruct>
{};

CRTP static polymorphism: is it possible to replace the base class with a mock?

I use CRTP static polymorphism in a websocket server to decouple networking code from business logic. The base class calls methods on the derived to process messages, the derived in turn calls the base to send/receive. It works like charm, looks something like this:
template<typename Derived>
class WebsocketSessionBase {
// basic websocket send/receive stuff
void someBaseMethod() {
static_cast<Derived*>(this)->otherDerivedMethod();
}
};
class WebsocketSession : public WebsocketSessionBase<WebsocketSession> {
// specific business logic
void someDerivedMethod() {
otherBaseMethod();
}
};
Now comes unit testing. Since the code is decoupled I would like the test functionality in the classes separately.
Testing the base class is simple:
class TestSession : public WebsocketSessionBase<TestSession> {
// same interface as WebsocketSession, but test code, cool!
};
But how do I test derived class? Adding a Base template parameter came to my mind, which makes test code ok (Base is a mock class). But I end up having 2 template classes referring to each other in the production version... :(
template<typename Base>
class TestableWebsocketSession : public Base {
};
using TestedWebsocketSession = TestableWebsocketSession<MockBase>;
using ProdWebSocketSession = TestableWebsocketSession<WebsocketSessionBase<... // infinite loop - now what!?
Is it possible to come over this?
I don't know if it's worth it, but you could make WebsocketSession a class template taking a template template parameter :
template<class T>
struct WebsocketSessionBase { /*...*/ };
template<template<class> class B>
struct WebsocketSessionDerived: B<WebsocketSessionDerived<B>>{ /*...*/ };
using WebsocketSession = WebsocketSessionDerived<WebsocketSessionBase>;
using DerivedTestSession = WebsocketSessionDerived<WebsocketSessionMockBase>;
struct BaseTestSession : WebsocketSessionBase<BaseTestSession>{ /*...*/ };

C++ Template Specialization with Inheritance

Following Situation:
class FeatureBase
class Feature1 : public FeatureBase
class FeatureAttrBase
class Feature1Attr : public FeatureAttrbase
FeatureBase contains a list of FeatureAttrBase and should be able to create and manage these objects. Therefore i use a template on FeatureBase.
template<class T = FeatureAttrBase> class FeatureBase
creating and managing the attributes (e.g. new T())
and the subclasses use a specialized inheritance
class Feature1 : public FeatureBase<Feature1Attr>
Anywhere else in my code i wrote a method
RegisterFeature(FeatureBase<FeatureAttrBase>* feature)
but the compiler gives me an error that it was unable to convert between Feature1 and FeatureBase. In the mentioned method i only need to use information from FeatureAttrBase. But inside Feature1 i need access to Feature1Attr.
Thus the question is how to solve this issue? Do i have to change my datastructure?
Having template parameters inherit from each other doesn't make template classes related. You should instead do something like the following (might not be the best solution but you haven't specified what you are trying to do):
class FeatureAttrBase;
class FeatureBase
{
public:
virtual FeatureAttrBase* GetAttributes() = 0;
};
template<class T>
class FeatureImpl : public FeatureBase
{
T attr;
public:
FeatureAttrBase* GetAttributes()
{
return &attr;
}
};
class Feature1Attr : public FeatureAttrBase;
class Feature1 : public FeatureImpl<Feature1Attr>;
In fact, you probably don't need the FeatureImpl class and can put the implementation directly in the Feature1 class (and get rid of templates completely).
You could inherit the specialisations of FeatureBase from FeatureBase<FeatureAttrBase>. Something like this:
// Forward declaration
template <typename T>
class FeatureBase;
// Type selecting trait class FeatureBase_BaseClass
// FeatureBase for derived Attrs will inherit from FeatureBase<FeatureAttrBase>
template <typename T>
struct FeatureBase_BaseClass
{
typedef FeatureBase<FeatureAttrBase> Type;
};
// FeatureBase<FeatureAttrBase> will inherit from a dummy type
template <>
struct FeatureBase_BaseClass<FeatureAttrBase>
{
struct Type {};
};
// Use FeatureBase_BaseClass to select the proper base class for FeatureBase
template <typename T = FeatureAttrBase>
class FeatureBase : public FeatureBase_BaseClass<T>::Type
{
//as before
};
This way, all FeatureBase<X> for specific attributes X will inherit from FeatureBase<FeatureAttrBase>.

Factory pattern and class templates in C++

I have a hierarchy of class templates. At the top of the hierarchy is an abstract base class (interface). I won't know which concrete implementation to instantiate until runtime, so it seems like the perfect situation to use the factory pattern. However, virtual member function templates are not allowed in C++.
How can I achieve a legal design similar to the below in C++?
The individual concrete implementations of the IProduct interface as well as the concrete factories will live in different dynamic libraries, one or more of which will be loaded at runtime.
template<class T> class IProduct
{
public:
virtual void doWork(const T & data) = 0;
};
template<class T> class ProductA : public IProduct<T> {/*...*/};
template<class T> class ProductB : public IProduct<T> {/*...*/};
class IProductFactory
{
public:
template<class T> virtual IProduct<T> * createProduct() = 0;
};
class ProductAFactory: public IProductFactory
{
public:
template<class T> virtual IProduct<T> * createProduct()
{
return new ProductA<T>;
}
};
class ProductBFactory: public IProductFactory
{
public:
template<class T> virtual IProduct<T> * createProduct()
{
return new ProductB<T>;
}
};
Why can't you templatize IProductFactory on T as well? That would get rid of your error, and it's no less general. The client is still going to have to know what T is in order to call thecreateProduct method.
Edit Re: comment
In order to do this, you will need to just create a templatized function to create the factory. So:
template<class T> IProductFactory<T>* getProductFactory();
Now your factory is templatized, the createProduct method is no longer a member template. Not sure what your criteria is for returning a ProductAFactory vs. a ProductBFactory but you will either have to pass in a string to choose, have this be a member function of another class that would make the decision, or have multiple free functions but only expose one version or another to a particular client.
This doesn't need a template. Does that eliminate your problem?

C++ Templates and Inheritance

Let's say I have a simple Server with a template which accepts a Client as it's template argument:
template<class T>
class Server<T>{
Server(int port);
}
and a Client is defined something like this:
class Client{
Client(Server<Client> *server, // <--
int socket);
};
But I also want say, have the class User inherit from Client (class User : public Client), so I could do Server<User> instead of Server<Client>. class User obviously needs to pass Server<Client> as a parameter when constructing Client. However, with the current implementation this seems impossible.
How should I approach this problem?
What about this?
template<class T>
class Server<T>{
Server(int port);
};
template<class Derived>
class Client {
Client(Server<Derived> *server, int socket);
virtual ~Client() {} // Base classes should have this
};
class User : public Client<User> {
};