C++ making a template class as place holder in another class - c++

I am trying to make a template class as placeholder class which can hold something like and string and type T object. Below is the code which I have written for the same.
#include <iostream>
#include <string>
#include <map>
using namespace std;
//A class which act as placeholder to hold
//unknown object. Something similar as Object
//in Java
template <typename T>
class Genric
{
public:
map<string, T> addP; //This will be placeholder for time
// being.
};
class A
{
public:
Genric t1; //Have object of Genric class so that we can
// access the member variable in future.
void foo()
{
cout<<"Calling foo"<<endl;
}
};
int main()
{
A a1;
a1.foo();
}
But when I tried to compile I am getting below error.
$ g++ tempClass.cxx
tempClass.cxx:21:9: error: invalid use of template-name 'Genric' without an argument list
The purpose of above Genric class is just to act as placeholder class for one of the member variables which can be populated in future.
So is there a way we can write such Genric class.

You are defining Genric as a template class, but then trying to initialize t1 without giving a type to it. That is the error you are getting. Try for example:
Genric<int> t1;
Or, if you are looking for a truly runtime generic, look into boost::any.

You need something like boost::any:
map<string, boost::any> anywayzz;
You can store any object in it. You don't need Genric class template.
If you're not using boost, then you can implement any yourself. Look for its implementation, or type-erasure, on this site. You will surely get some idea. Start from here:
Type erasure techniques

A template is "generic" until the program is compiled. At that point the compile must be made aware of what types it has to deal with.
If you want something that can contain a compile-time unknown (better: not yet known) type template are not the solution. Since the actual type will be known just at runtime, you have to go towards runtime-based polymorphism (inheritance from a polymorphic base) eventually wrapped inside an "handler".
In essence you need a base with at leas t a virtual function that allow you to check the type, and generic derived class that implement that function in a suitable way for all types.
boost::any can be an implementation, but there can be simpler ways, especially considering that "a function that allows to discover a runtime type" is no more than ... dynamic_cast.
You can so cometo a solution like this
#include <memory>
class any_value
{
template<class T>
class wrapper; //see below
class common_base
{
public:
virtual ~common_base() {} //this makes the type polymorphic
template<class T>
T* has_value()
{
auto* ptr = dynamic_cast<wrapper<T>*>(this);
return ptr? &ptr->m: nullptr;
}
};
template<class T>
class wrapper: public common_base
{
public:
wrapper() :m() {}
wrapper(const T& t) :m(t) {}
T m;
};
std::unique_ptr<common_base> pb;
public:
any_value() {}
template<class T>
any_value(const T& t) :pb(new wrapper<T>(t)) {}
template<class T>
any_value& operator=(const T& t)
{ pb = std::unique_ptr<common_base>(new wrapper<T>(t)); return *this; }
any_value(any_value&&) =default;
any_value& operator=(any_value&&) =default;
//NOW THE GETTERS
template<class T>
T* get() const //nullptr if not holding a T*
{ return bool(pb)? pb->has_value<T>(): nullptr; }
template<class T>
bool get(T& t)
{
T* pt = get<T>();
if(pt) t = *pt;
return bool(pt);
}
};
#include <iostream>
#include <string>
int main()
{
any_value a(5), b(2.7192818), c(std::string("as a string"));
int vi=0; double vd=0; std::string vs;
if(!a.get(vi)) vi=0; //will go
if(!a.get(vd)) vd=0; //will fail
if(!a.get(vs)) vs.clear(); //will fail
std::cout <<"vi = "<<vi<<", vd = "<<vd<<", vs = "<<vs<<" \n";
if(!b.get(vi)) vi=0; //will fail
if(!b.get(vd)) vd=0; //will go
if(!b.get(vs)) vs.clear(); //will fail
std::cout <<"vi = "<<vi<<", vd = "<<vd<<", vs = "<<vs<<" \n";
if(!c.get(vi)) vi=0; //will fail
if(!c.get(vd)) vd=0; //will fail
if(!c.get(vs)) vs.clear(); //will go
std::cout <<"vi = "<<vi<<", vd = "<<vd<<", vs = "<<vs<<" \n";
}
Following Abhinav comment:
Since the C++ type system is static, you cannot -in general- deserialize an "unknown", unless you first deserialize something that can be "Known".
For this you first need a way to represet a C++ type (not object) into an recognizable value (sort of type-uid), and a "factory" that creates the wrappers appropriated for those "values".
On saving, you just save that uid, then ask via a common_base virtual function to save the wrapped value.
On loading, you first load the uid, than create a new wrapper with appropriate type (see after) and than load the value via a common_base virtual function.
To create an appropriate wrapper, you need a table that maps the uid-s towards functions that create the wrapper associated with the type uid.
This table must be pre-initialized for all the types you need to be able to serialize / deserialize.
But this goes long away your original question, that doesn't speak about serialization/deserialization.
If the problem is "serialization", the "type erasure" is not a complete solution. You should much more look at the "factory pattern". And post another question better suited for that argument.

Related

Create a templated variable within a templated class of a different type

I'm not sure what I am asking for is possible.
I have a templated class called Controller. This is a variadic template class which takes multiple classes and can set their values as such.
Controller<ClassA,ClassB,ClassC>* myController = new Controller<ClassA,ClassB,ClassC>(*a,*b,*c);
myController->setValues(32);
This takes a bunch of different classes together and allows me to to set their values at the same time. setValues is a templated function which allows any type to be passed in. However, right now I am trying to modify my class so that I can set a value within the controller itself for easy retrieval. However this is the part that is proving difficult.
template<typename...Classes>
class Controller
{
public:
Controller(Classes&...objects) : objects(objects...){}
Controller(std::tuple<Classes&...> tup) : objects(tup){}
template<typename T>
void setValues(T value)
{
std::apply([&](auto&...x) { x.updateValue(value),...);}, objects); //calls the updateValue function for each class
}
private:
std::tuple<Classes&...> objects;
};
I want to add the following as a private variable T controllerValue; However, I know that I cannot simply declare T because we cannot define member templates and the compiler has no idea what to expect. Which then I tried to create a private struct:
template<typename T>
struct ControllerValue { T value; };
However, I cannot define a struct underneath that, because the same problem occurs. The compiler has no idea what type ControllerValue is. What I would like is something like this:
template<typename...Classes>
class Controller
{
public:
Controller(Classes&...objects) : objects(objects...){}
Controller(std::tuple<Classes&...> tup) : objects(tup){}
template<typename T>
void setValues(T value)
{
thisValue.value = value;
std::apply([&](auto&...x) { x.updateValue(value),...);}, objects); //calls the updateValue function for each class
}
template<typename T>
T getValue() const { return thisValue.value }
private:
std::tuple<Classes&...> objects;
template<typename T>
struct ControllerValue { T value; };
ControllerValue thisValue;
};
This will not compile at all for the same reason that the compiler has no idea what type ControllerValue should be. And this is where I am stuck. Is this even possible to do? If not, what is another way that I can make this work?
To clear up confusion, the use case would be something like this:
Controller<ClassA,ClassB,ClassC>* myController = new Controller<ClassA,ClassB,ClassC>(*a,*b,*c);
myController->setValues(32);
int commonValue = myController->getValue();
or
Controller<ClassA,ClassB,ClassC>* myController = new Controller<ClassA,ClassB,ClassC>(*a,*b,*c);
myController->setValues(32.3);
double commonValue = myController->getValue();
I think solving this exact problem is impossible in C++ (and still very cumbersome in languages with runtime generics). You can very easily create a polymorphic class that can only store any value:
class PolymorphicBase
{
public:
virtual ~PolymorphicBase() = default;
};
template <class T>
class PolymorphicObject : public PolymorphicBase
{
T value;
public:
PolymorphicObject(T value) : value(std::move(value))
{
}
};
A member of std::unique_ptr<PolymorphicBase> can sufficiently store any value, but how would such a value be retrieved? Probably the easiest is to expose the reference to PolymorphicBase and use dynamic type checks to see if the type is compatible with something you know, but what if you need the code to work for any type?
This is what lambdas with auto parameters are useful for. However, you would have to be able to pass such a lambda to a method on PolymorphicBase and implement that method in PolymorphicObject. This is impossible, since you cannot override a method template (it needs to be a template to accept a lambda) – that's where the compile-time and runtime parts of C++ clash. And there is simply no type in C++ that represents a function accepting any parameter (and knowing its type), which is a template by itself.
You can partially solve this by making the type of the lambda known to PolymorphicBase:
template <class Retriever>
class PolymorphicBase
{
public:
virtual void retrieve(Retriever func) = 0;
virtual ~PolymorphicBase() = default;
};
template <class Retriever, class T>
class PolymorphicObject : public PolymorphicBase<Retriever>
{
T value;
public:
PolymorphicObject(T value) : value(std::move(value))
{
}
void retrieve(Retriever func) override
{
func(value);
}
};
auto lambda = [](auto arg)
{
std::cout << arg << std::endl;
};
PolymorphicObject<decltype(lambda), int> obj(6);
PolymorphicBase<decltype(lambda)> &ptr = obj;
ptr.retrieve(lambda);
This is useful if you ever have only a single way to retrieve the value.
I don't think this is needed in most cases anyway. Usually you use a fixed set of types as the values, so you can use a variant there, or they all implement a common interface, or (as you've pointed out in the comments) you actually meant to move the type parameter from the method to the class (which allows you to check that all the types actually support the value earlier than originally).
However, I agree that in languages with generics/templates it is somewhat hard to have a method that can actually choose its result type in a generic fashion, without being controlled by outside parameters.

Is there a way to prevent assignment of pointers?

A tricky question. If would like to write a function that returns a pointer to some IFoo object, is it possible to prevent the assignment of this pointer?
I do not want to make IFoo a singleton and I can hide or delete the copy and assignment operators, but does C++ actually allow a pattern, where I explicitly have to call somebody else to obtain an object?
The background question is: I am thinking about some sort of dependency container, where you should always ask the container to get some IFoo * (pointer for the sake of polymorphism). The user should never be able to save it to some local variable or member to avoid a stalled reference to it. (For scenarios where the container is instructed to return no longer Foo, which is derived from IFoo but Bar)
Edit for clarification, although user R Sahu already said that is not possible.
Indeed the example of Mark B was a perfect illustration of what I wanted to prevent:
IFoo* foo_ptr_I_will_keep_forever = obj->getIFoo();
When I wouldn't have interfaces but only explicit instance of types I could return a reference, which given a private operator= and copy ctor would suffice.
Your title says:
Is there a way to prevent assignment of pointers?
No, you can't prevent that if your function returns a pointer.
However, if you return a handle, which can be a pointer to a type that is only forward declared or an integral value that can be used to come up the real object, and make sure that all the real functionality works with the handle, then you can have more freedom over when you can delete the real object without the risk of leaving the client code with a dangling pointer.
Here's a simple program that demonstrates the concept.
#include <iostream>
#include <set>
// Foo.h
struct Foo;
using FooHandle = Foo*;
FooHandle createFoo();
void fooFunction1(FooHandle h);
void fooFunction2(FooHandle h);
// Test Program
int main()
{
FooHandle h = createFoo();
fooFunction1(h);
fooFunction2(h);
fooFunction1(h);
return 0;
}
// Foo implementation.
namespace FooImpl
{
std::set<Foo*>& getLiveFooObjects()
{
static std::set<Foo*> liveObjects;
return liveObjects;
}
bool isValid(Foo* h)
{
return (getLiveFooObjects().find(h) != getLiveFooObjects().end());
}
}
using namespace FooImpl;
struct Foo {};
FooHandle createFoo()
{
FooHandle h = new Foo{};
getLiveFooObjects().insert(h);
return h;
}
void fooFunction1(FooHandle h)
{
if ( isValid(h) )
{
std::cout << "In fooFunction1.\n";
}
else
{
std::cout << "Ooops. The handle is no longer valid.\n";
}
}
void fooFunction2(FooHandle h)
{
std::cout << "In fooFunction2.\n";
delete h;
getLiveFooObjects().erase(h);
}
Output:
In fooFunction1.
In fooFunction2.
Ooops. The handle is no longer valid.
Give them back an object (that they can store if they want) that always looks up the real one via private (friend) interfaces.
For example, an IFooCaller that implements IFoo by getting the current IFoo and forwarding all calls to it.
A middle ground answer that would prevent accidentally storing a pointer to a particular implementation, but wouldn't prevent someone from doing it on purpose:
template <typename T> class service_wrapper;
class service_manager
{
template <typename T> friend class service_wrapper;
public:
template <typename T>
service_wrapper<T> get() const;
private:
template <typename T>
T* get_instance() const;
};
template <typename T>
class service_wrapper
{
friend class service_manager;
public:
T* operator->() const;
private:
service_wrapper(service_manager const & p_sm) : sm(p_sm) { }
service_manager const & sm;
};
template <typename T>
T* service_wrapper<T>::operator->() const
{
return sm.get_instance<T>();
}
Your manager only dispenses instances of service_wrapper<T>. The operator-> implementation allows invoking on the service using wrapper->method(...);, and always fetches the implementation pointer from the service manager.
This can be circumvented like:
T *ptr = sm.get<T>().operator->();
But that's not something you can accidentally do.

Storing multiple types into the same container [duplicate]

This question already has answers here:
Heterogeneous containers in C++
(7 answers)
Closed 8 years ago.
Introduction
Say I have the follow
class thing {
template<typename T> void method(T value) {}
}
What I want to do is to store whatever value is passed into value no matter what type into a std::vector or something and without turning this into a template class (because that doesn't solve my problem in anyway)
I want to be able to do this without using boost (as much i love boost i am not going to use it all the time)
Attempted Ideas
Void Pointer
My initial though is to use a void* however i would lose the type of the object and it could end up being unsafe.
Union/Struct
My next thought was to use a union/struct like the one below:
union type_wrapper {
int a;
char f;
/* etc, etc, etc */
}
However i would run into the same problem as I would have to track the type, so i make sure it remains the same when ever used.
Wrapper Class
Then next thing i attempted was a class that would return the type in a function call like so:
template<typename T>
class type_wrapper {
T getType() { return /* get value of type/pointer/object here */ }
/*Stored in some manner */
}
Problem with is the same thing as with just the type on its own in that it cannot be stored in a list called lets say std::list<AClass> when its of type std::list<BClass> or std::list<int> etc
Other thing
All other examples i have looked at have do what i am doing but are expect that you track the type of the object one way or another, or use boost.
tl;dr
What could i try doing so that i could pass a parameter of type int and storing into a std::list etc it while using the same template function to pass a parameter of type 'cheese' (an imaginary class dedicated to filling your programs with cheese) and storing it into the same list, etc
I don't know if this will solve your problem, but you can use some polymorphic type for the container, and encapsulate the object in a generic derived class, so calls to object's member functions from the derived class' member functions can have full type information (they will be specialized templates), but your "thing" won't be generic, and client code won't care (or even know) about this inhertance:
class Aux {
public:
virtual void DoSomething() =0 ;
};
template<typename T>
class AuxTemp : public Aux {
T *real_obj;
public:
AuxTemp(const T &obj) : real_obj(new T(obj)) {} // create
AuxTemp(const AuxTemp &other) : real_obj(new T(*other.real_obj)) { } // copy
AuxTemp(AuxTemp &&other) : real_obj(other.real_obj) { other.real_obj=nullptr; } // move
~AuxTemp() { delete real_obj; } // destroy
void DoSomething() override {
real_obj->DoSomething(); // here we call the method with full type information for real_obj
}
};
class Thing {
std::vector<Aux*> v;
public:
template<typename T> void Add(const T &value) {
v.push_back(new AuxTemp<T>(value));
}
void DoSomethingForAll() {
for(auto &x:v) x->DoSomething();
}
};
Yo can test this with:
class A {
public:
void DoSomething() { std::cout << "A"<< std::endl; }
};
class B {
public:
void DoSomething() { std::cout << "B"<< std::endl; }
};
int main(int argc, char *argv[]) {
Thing t;
t.Add(A{});
t.Add(B{});
t.DoSomethingForAll();
return 0;
}
For each new type you push to your vector, a new derived and specialized wrapper class is made by Add member function, so virtual table can handle calls to DoSomething in order to use the proper and full-aware-of-real-type version.
I think what I propose is a bizarre implementation "type-erasure" (you should google for this term to find more elaborated solutions).

Elegant way to implement extensible factories in C++

I am looking for an intuitive and extensible way to implement factories for subclasses of a given base class in c++. I want to provide such a factory function in a library.The tricky part is that I want said factory to work for user-defined subclasses as well (e.g. having the library's factory function build different subclasses depending on what modules are linked to it). The goal is to have minimal burden/confusion for downstream developers to use the factories.
An example of what I want to do is: given a std::istream, construct and return an object of whatever subclass matches the content, or a null pointer if no matches are found. The global factory would have a signature like:
Base* Factory(std::istream &is){ ... };
I am familiar with prototype factories, but I prefer to avoid the need to make/store prototype objects. A related question is posted here for java: Allowing maximal flexibly/extensibility using a factory.
I am not looking for c++11-specific solutions at the moment, but if they are more elegant I would be happy to learn about those.
I came up with one working solution which I believe is fairly elegant, which I will post as an answer. I can imagine this problem to be fairly common, so I am wondering if anyone knows of better approaches.
EDIT: it seems some clarification is in order...
The idea is for the factory to construct an object of a derived class, without containing the logic to decide which one. To make matters worse, the factory method will end up as part of a library and derived classes may be defined in plugins.
Derived classes must be able to decide for themselves whether or not they are fit for construction, based on the input provided (for example an input file). This decision can be implemented as a predicate that can be used by the factory, as was suggested by several people (great suggestion, by the way!).
If I understand this correctly, we want a factory function that can select which derived class to instantiate based on constructor inputs. This is the most generic solution that I could come up with so far. You specify mapping inputs to organize factory functions, and then you can specify constructor inputs upon factory invocation. I hate to say that the code explains more than I could in words, however I think the example implementations of FactoryGen.h in Base.h and Derived.h are clear enough with the help of comments. I can provide more details if necessary.
FactoryGen.h
#pragma once
#include <map>
#include <tuple>
#include <typeinfo>
//C++11 typename aliasing, doesn't work in visual studio though...
/*
template<typename Base>
using FactoryGen<Base> = FactoryGen<Base,void>;
*/
//Assign unique ids to all classes within this map. Better than typeid(class).hash_code() since there is no computation during run-time.
size_t __CLASS_UID = 0;
template<typename T>
inline size_t __GET_CLASS_UID(){
static const size_t id = __CLASS_UID++;
return id;
}
//These are the common code snippets from the factories and their specializations.
template<typename Base>
struct FactoryGenCommon{
typedef std::pair<void*,size_t> Factory; //A factory is a function pointer and its unique type identifier
//Generates the function pointer type so that I don't have stupid looking typedefs everywhere
template<typename... InArgs>
struct FPInfo{ //stands for "Function Pointer Information"
typedef Base* (*Type)(InArgs...);
};
//Check to see if a Factory is not null and matches it's signature (helps make sure a factory actually takes the specified inputs)
template<typename... InArgs>
static bool isValid(const Factory& factory){
auto maker = factory.first;
if(maker==nullptr) return false;
//we have to check if the Factory will take those inArgs
auto type = factory.second;
auto intype = __GET_CLASS_UID<FPInfo<InArgs...>>();
if(intype != type) return false;
return true;
}
};
//template inputs are the Base type for which the factory returns, and the Args... that will determine how the function pointers are indexed.
template<typename Base, typename... Args>
struct FactoryGen : FactoryGenCommon<Base>{
typedef std::tuple<Args...> Tuple;
typedef std::map<Tuple,Factory> Map; //the Args... are keys to a map of function pointers
inline static Map& get(){
static Map factoryMap;
return factoryMap;
}
template<typename... InArgs>
static void add(void* factory, const Args&... args){
Tuple selTuple = std::make_tuple(args...); //selTuple means Selecting Tuple. This Tuple is the key to the map that gives us a function pointer
get()[selTuple] = Factory(factory,__GET_CLASS_UID<FPInfo<InArgs...>>());
}
template<typename... InArgs>
static Base* make(const Args&... args, const InArgs&... inArgs){
Factory factory = get()[std::make_tuple(args...)];
if(!isValid<InArgs...>(factory)) return nullptr;
return ((FPInfo<InArgs...>::Type)factory.first) (inArgs...);
}
};
//Specialize for factories with no selection mapping
template<typename Base>
struct FactoryGen<Base,void> : FactoryGenCommon<Base>{
inline static Factory& get(){
static Factory factory;
return factory;
}
template<typename... InArgs>
static void add(void* factory){
get() = Factory(factory,__GET_CLASS_UID<FPInfo<InArgs...>>());
}
template<typename... InArgs>
static Base* make(const InArgs&... inArgs){
Factory factory = get();
if(!isValid<InArgs...>(factory)) return nullptr;
return ((FPInfo<InArgs...>::Type)factory.first) (inArgs...);
}
};
//this calls the function "initialize()" function to register each class ONCE with the respective factory (even if a class tries to initialize multiple times)
//this step can probably be circumvented, but I'm not totally sure how
template <class T>
class RegisterInit {
int& count(void) { static int x = 0; return x; } //counts the number of callers per derived
public:
RegisterInit(void) {
if ((count())++ == 0) { //only initialize on the first caller of that class T
T::initialize();
}
}
};
Base.h
#pragma once
#include <map>
#include <string>
#include <iostream>
#include "Procedure.h"
#include "FactoryGen.h"
class Base {
public:
static Base* makeBase(){ return new Base; }
static void initialize(){ FactoryGen<Base,void>::add(Base::makeBase); } //we want this to be the default mapping, specify that it takes void inputs
virtual void speak(){ std::cout << "Base" << std::endl; }
};
RegisterInit<Base> __Base; //calls initialize for Base
Derived.h
#pragma once
#include "Base.h"
class Derived0 : public Base {
private:
std::string speakStr;
public:
Derived0(std::string sayThis){ speakStr=sayThis; }
static Base* make(std::string sayThis){ return new Derived0(sayThis); }
static void initialize(){ FactoryGen<Base,int>::add<std::string>(Derived0::make,0); } //we map to this subclass via int with 0, but specify that it takes a string input
virtual void speak(){ std::cout << speakStr << std::endl; }
};
RegisterInit<Derived0> __d0init; //calls initialize() for Derived0
class Derived1 : public Base {
private:
std::string speakStr;
public:
Derived1(std::string sayThis){ speakStr=sayThis; }
static Base* make(std::string sayThat){ return new Derived0(sayThat); }
static void initialize(){ FactoryGen<Base,int>::add<std::string>(Derived0::make,1); } //we map to this subclass via int with 1, but specify that it takes a string input
virtual void speak(){ std::cout << speakStr << std::endl; }
};
RegisterInit<Derived1> __d1init; //calls initialize() for Derived1
Main.cpp
#include <windows.h> //for Sleep()
#include "Base.h"
#include "Derived.h"
using namespace std;
int main(){
Base* b = FactoryGen<Base,void>::make(); //no mapping, no inputs
Base* d0 = FactoryGen<Base,int>::make<string>(0,"Derived0"); //int mapping, string input
Base* d1 = FactoryGen<Base,int>::make<string>(1,"I am Derived1"); //int mapping, string input
b->speak();
d0->speak();
d1->speak();
cout << "Size of Base: " << sizeof(Base) << endl;
cout << "Size of Derived0: " << sizeof(Derived0) << endl;
Sleep(3000); //Windows & Visual Studio, sry
}
I think this is a pretty flexible/extensible factory library. While the code for it is not very intuitive, I think using it is fairly simple. Of course, my view is biased seeing as I'm the one that wrote it, so please let me know if it is the contrary.
EDIT : Cleaned up the FactoryGen.h file. This is probably my last update, however this has been a fun exercise.
My comments were probably not very clear. So here is a C++11 "solution" relying on template meta programming : (Possibly not the nicest way of doing this though)
#include <iostream>
#include <utility>
// Type list stuff: (perhaps use an existing library here)
class EmptyType {};
template<class T1, class T2 = EmptyType>
struct TypeList
{
typedef T1 Head;
typedef T2 Tail;
};
template<class... Etc>
struct MakeTypeList;
template <class Head>
struct MakeTypeList<Head>
{
typedef TypeList<Head> Type;
};
template <class Head, class... Etc>
struct MakeTypeList<Head, Etc...>
{
typedef TypeList<Head, typename MakeTypeList<Etc...>::Type > Type;
};
// Calling produce
template<class TList, class BaseType>
struct Producer;
template<class BaseType>
struct Producer<EmptyType, BaseType>
{
template<class... Args>
static BaseType* Produce(Args... args)
{
return nullptr;
}
};
template<class Head, class Tail, class BaseType>
struct Producer<TypeList<Head, Tail>, BaseType>
{
template<class... Args>
static BaseType* Produce(Args... args)
{
BaseType* b = Head::Produce(args...);
if(b != nullptr)
return b;
return Producer<Tail, BaseType>::Produce(args...);
}
};
// Generic AbstractFactory:
template<class BaseType, class Types>
struct AbstractFactory {
typedef Producer<Types, BaseType> ProducerType;
template<class... Args>
static BaseType* Produce(Args... args)
{
return ProducerType::Produce(args...);
}
};
class Base {}; // Example base class you had
struct Derived0 : public Base { // Example derived class you had
Derived0() = default;
static Base* Produce(int value)
{
if(value == 0)
return new Derived0();
return nullptr;
}
};
struct Derived1 : public Base { // Another example class
Derived1() = default;
static Base* Produce(int value)
{
if(value == 1)
return new Derived1();
return nullptr;
}
};
int main()
{
// This will be our abstract factory type:
typedef AbstractFactory<Base, MakeTypeList<Derived0, Derived1>::Type> Factory;
Base* b1 = Factory::Produce(1);
Base* b0 = Factory::Produce(0);
Base* b2 = Factory::Produce(2);
// As expected b2 is nullptr
std::cout << b0 << ", " << b1 << ", " << b2 << std::endl;
}
Advantages:
No (additional) run-time overhead as you would have with the function pointers.
Works for any base type, and for any number of derived types. You still end up calling the functions of course.
Thanks to variadic templates this works with any number of arguments (giving an incorrect number of arguments will produce a compile-time error message).
Explicit registering of the produce member functions
is not required.
Disadvantages:
All of your derived types must be available when you declare the
Factory type. (You must know what the possible derived types are and they must be complete.)
The produce member functions for the derived types must be public.
Can make compilation slower. (As always the case when relying on template metaprogramming)
In the end, using the prototype design pattern might turn out better. I don't know since I haven't tried using my code.
I'd like to state some additional things (after further discussion on the chat):
Each factory can only return a single object. This seems strange, as the users decide whether they will take the input to create their object or not. I would for that reason suggest your factory can return a collection of objects instead.
Be careful not to overcomplicate things. You want a plugin system, but I don't think you really want factories. I would propose you simply make users register their classes (in their shared object), and that you simply pass the arguments to the classes' Produce (static) member functions. You store the objects if and only if they're not the nullptr.
Update: This answer made the assumption that some kind of magic existed that could be read and passed to the factory, but that's apparently not the case. I'm leaving the answer here because a) I may update it, and b) I like it anyway.
Not hugely different from your own answer, not using C++11 techniques (I've not had a chance to update it yet, or have it return a smart pointer, etc), and not entirely my own work, but this is the factory class I use. Importantly (IMHO) it doesn't call each possible class's methods to find the one that matches - it does this via the map.
#include <map>
// extraneous code has been removed, such as empty constructors, ...
template <typename _Key, typename _Base, typename _Pred = std::less<_Key> >
class Factory {
public:
typedef _Base* (*CreatorFunction) (void);
typedef std::map<_Key, CreatorFunction, _Pred> _mapFactory;
// called statically by all classes that can be created
static _Key Register(_Key idKey, CreatorFunction classCreator) {
get_mapFactory()->insert(std::pair<_Key, CreatorFunction>(idKey, classCreator));
return idKey;
}
// Tries to create instance based on the key
static _Base* Create(_Key idKey) {
_mapFactory::iterator it = get_mapFactory()->find(idKey);
if (it != get_mapFactory()->end()) {
if (it->second) {
return it->second();
}
}
return 0;
}
protected:
static _mapFactory * get_mapFactory() {
static _mapFactory m_sMapFactory;
return &m_sMapFactory;
}
};
To use this you just declare the base-type, and for each class you register it as a static. Note that when you register, the key is returned, so I tend to add this as a member of the class, but it's not necessary, just neat :) ...
// shape.h
// extraneous code has been removed, such as empty constructors, ...
// we also don't technically need the id() method, but it could be handy
// if at a later point you wish to query the type.
class Shape {
public:
virtual std::string id() const = 0;
};
typedef Factory<std::string, Shape> TShapeFactory;
Now we can create a new derived class, and register it as creatable by TShapeFactory...
// cube.h
// extraneous code has been removed, such as empty constructors, ...
class Cube : public Shape {
protected:
static const std::string _id;
public:
static Shape* Create() {return new Cube;}
virtual std::string id() const {return _id;};
};
// cube.cpp
const std::string Cube::_id = TShapeFactory::Register("cube", Cube::Create);
Then we can create a new item based on, in this case, a string:
Shape* a_cube = TShapeFactory::Create("cube");
Shape* a_triangle = TShapeFactory::Create("triangle");
// a_triangle is a null pointer, as we've not registered a "triangle"
The advantage of this method is that if you create a new derived, factory-generatable class, you don't need to change any other code, providing you can see the factory class and derive from the base:
// sphere.h
// extraneous code has been removed, such as empty constructors, ...
class Sphere : public Shape {
protected:
static const std::string _id;
public:
static Shape* Create() {return new Sphere;}
virtual std::string id() const {return _id;};
};
// sphere.cpp
const std::string Sphere::_id = TShapeFactory::Register("sphere", Sphere::Create);
Possible improvements that I'll leave to the reader include adding things like: typedef _Base base_class to Factory, so that when you've declared your custom factory, you can make your classes derive from TShapeFactory::base_class, and so on. The Factory should probably also check if a key already exists, but again... it's left as an exercise.
The best solution I can currently think of is by using a Factory class which stores pointers to producing functions for each derived class. When a new derived class is made, a function pointer to a producing method can be stored in the factory.
Here is some code to illustrate my approach:
#include <iostream>
#include <vector>
class Base{};
// Factory class to produce Base* objects from an int (for simplicity).
// The class uses a list of registered function pointers, which attempt
// to produce a derived class based on the given int.
class Factory{
public:
typedef Base*(*ReadFunPtr)(int);
private:
static vector<ReadFunPtr> registeredFuns;
public:
static void registerPtr(ReadFunPtr ptr){ registeredFuns.push_back(ptr); }
static Base* Produce(int value){
Base *ptr=NULL;
for(vector<ReadFunPtr>::const_iterator I=registeredFuns.begin(),E=registeredFuns.end();I!=E;++I){
ptr=(*I)(value);
if(ptr!=NULL){
return ptr;
}
}
return NULL;
}
};
// initialize vector of funptrs
std::vector<Factory::ReadFunPtr> Factory::registeredFuns=std::vector<Factory::ReadFunPtr>();
// An example Derived class, which can be produced from an int=0.
// The producing method is static to avoid the need for prototype objects.
class Derived : public Base{
private:
static Base* ProduceDerivedFromInt(int value){
if(value==0) return new Derived();
return NULL;
}
public:
Derived(){};
// registrar is a friend because we made the producing function private
// this is not necessary, may be desirable (e.g. encapsulation)
friend class DerivedRegistrar;
};
// Register Derived in the Factory so it will attempt to construct objects.
// This is done by adding the function pointer Derived::ProduceDerivedFromInt
// in the Factory's list of registered functions.
struct DerivedRegistrar{
DerivedRegistrar(){
Factory::registerPtr(&(Derived::ProduceDerivedFromInt));
}
} derivedregistrar;
int main(){
// attempt to produce a Derived object from 1: should fail
Base* test=Factory::Produce(1);
std::cout << test << std::endl; // outputs 0
// attempt to produce a Derived object from 0: works
test=Factory::Produce(0);
std::cout << test << std::endl; // outputs an address
}
TL;DR: in this approach, downstream developers need to implement the producing function of a derived class as a static member function (or a non-member function) and register it in the factory using a simple struct.
This seems simple enough and does not require any prototype objects.
Here is a sustainable idiom for managing factories that resolve at runtime. I've used this in the past to support fairly sophisticated behavior. I favor simplicity and maintainability without giving up much in the way of functionality.
TLDR:
Avoid static initialization in general
Avoid "auto-loading" techniques like the plague
Communicate ownership of objects AND factories
Separate usage and factory management concerns
Using Runtime Factories
Here is the base interface that users of this factory system will interact with. They shouldn't need to worry about the details of the factory.
class BaseObject {
public:
virtual ~BaseObject() {}
};
BaseObject* CreateObjectFromStream(std::istream& is);
As an aside, I would recommend using references, boost::optional, or shared_ptr instead of raw pointers. In a perfect world, the interface should tell me who owns this object. As a user, am I responsible for deleting this pointer when it's given to me? It's painfully clear when it's a shared_ptr.
Implementing Runtime Factories
In another header, put the details of managing the scope of when the factories are active.
class RuntimeFactory {
public:
virtual BaseObject* create(std::istream& is) = 0;
};
void RegisterRuntimeFactory(RuntimeFactory* factory);
void UnregisterRuntimeFactory(RuntimeFactory* factory);
I think the salient point in all of this is that usage is a different concern from how the factories are initialized and used.
We should note that the callers of these free functions own the factories. The registry does not own them.
This isn't strictly necessary, though it offers more control when and where these factories get destroyed. The point where it matters is when you see things like "post-create" or "pre-destroy" calls. Factory methods with these sorts of names are design smells for ownership inversion.
Writing another wrapper around this to manage the factories life-time would be simple enough anyway. It also lends to composition, which is better.
Registering Your New Factory
Write wrappers for each factory registration. I usually put each factory registration in its own header. These headers are usually just two function calls.
void RegisterFooFactory();
void UnregisterFooFactory();
This may seem like overkill, but this sort of diligence keeps your compile times down.
My main then is reduced to a bunch of register and unregister calls.
#include <foo_register.h>
#include <bar_register.h>
int main(int argc, char* argv[]) {
SetupLogging();
SetupRuntimeFactory();
RegisterFooFactory();
RegisterBarFactory();
// do work...
UnregisterFooFactory();
UnregisterBarFactory();
CleanupLogging();
return 0;
}
Avoid Static Init Pitfalls
This specifically avoids objects created during static loading like some of the other solutions. This is not an accident.
The C++ spec won't give you useful assurances about when static loading will occur
You'll get a stack trace when something goes wrong
The code is simple, direct, easy to follow
Implementing the Registry
Implementation details are fairly mundane, as you'd imagine.
class RuntimeFactoryRegistry {
public:
void registerFactory(RuntimeFactory* factory) {
factories.insert(factory);
}
void unregisterFactory(RuntimeFactory* factory) {
factories.erase(factory);
}
BaseObject* create(std::istream& is) {
std::set<RuntimeFactory*>::iterator cur = factories.begin();
std::set<RuntimeFactory*>::iterator end = factories.end();
for (; cur != end; cur++) {
// reset input?
if (BaseObject* obj = (*cur)->create(is)) {
return obj;
}
}
return 0;
}
private:
std::set<RuntimeFactory*> factories;
};
This assumes that all factories are mutually exclusive. Relaxing this assumption is unlikely to result in well-behaving software. I'd probably make stronger claims in person, hehe. Another alternative would be to return a list of objects.
The below implementation is static for simplicity of demonstration. This can be a problem for multi-threaded environments. It doesn't have to be static, nor do I recommend it should or shouldn't be static, it just is here. It isn't really the subject of the discussion, so I'll leave it at that.
These free functions only act as pass-through functions for this implementation. This lets you unit test the registry or reuse it if you were so inclined.
namespace {
static RuntimeFactoryRegistry* registry = 0;
} // anon
void SetupRuntimeFactory() {
registry = new RuntimeFactoryRegistry;
}
void CleanupRuntimeFactory() {
delete registry;
registry = 0;
}
BaseObject* CreateObjectFromStream(std::istream& is) {
return registry->create(is);
}
void RegisterRuntimeFactory(RuntimeFactory* factory) {
registry->registerFactory(factory);
}
void UnregisterRuntimeFactory(RuntimeFactory* factory) {
registry->unregisterFactory(factory);
}
First, there's not really enough detail here to form an opinion, so I'm left to guess. You've provided a challenging question and a minimal solution, but not clarified what is wrong with your solution.
I suspect the complaint centers around the reset back to knowing nothing between a refused construction and the following construction attempts. Given a very large number of potential factories this reset could have us parsing the same data hundreds or thousands of times. If this is the problem the question is this: how do you structure the predicate evaluation phase to limit the amount of work, and allow it to reuse previous parsing results.
I suggest having each factory register with:
1) a factory builder function taking the specialization parameter(s) (iostream in the example)
2) an unordered set of boolean predicates
3) required boolean values of each predicate to allow construction
The set of predicates is used to create/modify the predicate tree. Interior nodes in the tree represent predicates (branching to 'pass', 'fail', and possibly 'don't care'). Both interior nodes and leaves hold constructors which are satisfied if the ancestral predicates are satisfied. As you traverse the tree you first look for constructors at the current level, then evaluate the predicate and follow the required path. If no solution is found along that child path the follow the 'don't care' path.
This allows new factories to share predicate functions. There's probably lots of questions about managing/sorting the tree when the factories go on/off line. There's also the possibility of parser state data that needs to be retained across predicates and reset when construction is completed. There's lots of open questions, but this may work toward addressing the perceived problems with your solution.
TL:DR; Create a graph of predicates to traverse when attempting construction.
Simple solution is just a switch-case:
Base *create(int type, std::string data) {
switch(type) {
case 0: return new Derived1(data);
case 1: return new Derived2(data);
};
}
But then it's just deciding which type you want:
int type_of_obj(string s) {
int type = -1;
if (isderived1(s)) type=0;
if (isderived2(s)) type=1;
return type;
}
Then it's just connecting the two:
Base *create_obj(string s, string data,
Base *(*fptr)(int type, string data),
int (*fptr2)(string s))
{
int type = fptr2(s);
if (type==-1) return 0;
return fptr(type, data);
}
Then it's just registering the function pointers:
class Registry {
public:
void push_back(Base* (*fptr)(int type, string data),
int (*fptr2)(string s));
Base *create(string s, string data);
};
The plugin will have the 2 functions, and the following:
void register_classes(Registry &reg) {
reg.push_back(&create, &type_of_obj);
...
}
Plugin loader will dlopen/dlsym the register_classes functions.
(on the other hand, I'm not using this kind of plugins myself because creating new plugins is too much work. I have better way to provide modularity for my program's pieces. What kills plugins is the fact that you need to modify your build system to create new dll's or shared_libs, and doing that is just too much work - ideally new module is just one class; without anything more complicated build system modifications)

How do I make my Factory's Header not dependent on the templated objects it creates?

I have an abstract base class like so:
class AbstractBaseClass
{};
a templated concrete class that derives from it:
template<class T>
class ConcreteClass : public AbstractBaseClass
{
public:
ConcreteClass(T input) : data(input) {}
private:
T data;
};
AndI have a factory class that creates AbstractBaseClasses
class MyFactory
{
public:
boost::shared_ptr<AbstractBaseClass> CreateBlah();
boost::shared_ptr<AbstractBaseClass> CreateFoo();
template<class T>
boost::shared_ptr<AbstractBaseClass> Create(T input)
{
return boost::shared_ptr<AbstractBaseClass>(new ConcreteClass<T>(input));
}
};
The problem with this, is that now EVERYTHING that uses MyFactory has to include the entire implementation to ConcreteClass. Ideally, I want nothing but MyFactory to know about ConcreteClass.
Is there any way to architect this to achieve this goal? (Besides manually making a new Create function in MyFactory for every type I want instead of templating it).
you'll need to put the factory implementation into the implementation file (which you mentioned you'd like to avoid, but it is the lesser evil unless the interfaces are small, and/or your projects are small).
of course, there are a few other ways you could approach this, such as putting the implementation into base classes, and making derived bases factories, or using some other really weird template syntax to reduce instantiations in dependent translations. this really comes down to convenience and scale for your project. if you are working on one or more large projects, then full abstraction wrt instantiation will serve your needs best in the long run (assuming you need dynamic polymorphism and memory).
you may also try other approaches (such as overloading) to reduce errors by using type-safety.
the short answer is that you'll really need to abstract the interfaces/instantiation into one or multiple implementation files to remove header dependencies - very common idiom, and many ways to tackle it. you can over course further divide and use polymorphism for your factories as well.
you may also use template forward declarations to minimize the sets to the compilation unit. provided:
/** in MyIntermediateFactory.hpp */
class MyIntermediateFactory {
public:
static template<class T> boost::shared_ptr<T> Create(float);
};
/** in Concrete.hpp */
template<Concrete>
boost::shared_ptr<T> MyIntermediateFactory::Create<Concrete>(float arg) {
/* … */
}
using this you can select portions of programs/interfaces which you need in the library, then wrap it all up in a real Factory (for the build at hand). the linker/instantiation should fail along the way if you actually attempt to request a creation which is not visible.
there a lot of options, really - you need to figure out how big your scale is in order to determine what to abstract (or not). instantiation requires interface, to remove header dependencies, you'll have to abstract the instantiation someplace.
My approach to the same problem in the past was the creation of a set of concrete factories (one per type) that get registered in the global factory (for illustration purposes, indexing by object name):
class AbstractBaseClass;
class ConcreteFactory
{
public:
AbstractBaseClass * create();
};
class AbstractFactory
{
public:
void registerFactory( std::string const & name, std::shared_ptr<ConcreteFactory> const & f )
{
factory[ name ] = f; // check for collisions, complain if so ...
}
AbstractBaseClass * create( std::string const & name )
{
return factory[name]->create(); // check for existence before dereferencing...
}
private:
std::map<std::string, std::shared_ptr<ConcreteFactory> > factory;
};
I used this in a piece of code that was heavily templated to reduce compilation time. Each concrete factory and the class that it creates need only be in a single translation unit that registers the concrete factory. The rest of the code only need to use the common interface to AbstractBaseClass.
I realize I am answering this five years later. Maybe the language has grown a tad since then. I'd like to offer something that seems right, if I understand the question properly, if for no other point than to help others who might find this question and wonder what they could do.
factory.hpp
#include "base.hpp"
namespace tvr
{
namespace test
{
class factory
{
public:
typedef base::ptr Ptr;
enum eSpecial
{
eDerived
};
template<typename Type>
Ptr create()
{
Ptr result;
result.reset(new Type());
return result;
}
template<typename Type, typename DataType>
Ptr create(const DataType& data)
{
Ptr result;
result.reset(new Type(data));
return result;
}
template<typename Type, typename DataType>
Ptr create(const DataType& data, eSpecial tag)
{
Ptr result;
result.reset(new Type());
static_cast<Type*>(result.get())->set_item(data);
return result;
}
};
}
}
base.hpp
#include <memory>
namespace tvr
{
namespace test
{
class base
{
public:
typedef std::shared_ptr<base> ptr;
public:
base() {}
virtual ~base() {}
virtual void do_something() = 0;
};
}
}
some_class.hpp
#include <ostream>
namespace tvr
{
namespace test
{
struct some_class
{
};
}
}
std::ostream& operator<<(std::ostream& out, const tvr::test::some_class& item)
{
out << "This is just some class.";
return out;
}
template_derived.hpp
#include <iostream>
#include "base.hpp"
namespace tvr
{
namespace test
{
template<typename Type>
class template_derived : public base
{
public:
template_derived(){}
virtual ~template_derived(){}
virtual void do_something()
{
std::cout << "Doing something, like printing _item as \"" << _item << "\"." << std::endl;
}
void set_item(const Type data)
{
_item = data;
}
private:
Type _item;
};
}
}
and, finally, main.cpp
#include <vector>
#include "base.hpp"
#include "factory.hpp"
namespace tvr
{
namespace test
{
typedef std::vector<tvr::test::base::ptr> ptr_collection;
struct iterate_collection
{
void operator()(const ptr_collection& col)
{
for (ptr_collection::const_iterator iter = col.begin();
iter != col.end();
++iter)
{
iter->get()->do_something();
}
}
};
}
}
#include "template_derived.hpp"
#include "some_class.hpp"
namespace tvr
{
namespace test
{
inline int test()
{
ptr_collection items;
tvr::test::factory Factory;
typedef template_derived<unsigned int> UIntConcrete;
typedef template_derived<double> DoubleConcrete;
typedef template_derived<std::string> StringConcrete;
typedef template_derived<some_class> SomeClassConcrete;
items.push_back(Factory.create<SomeClassConcrete>(some_class(), tvr::test::factory::eDerived));
for (unsigned int i = 5; i < 7; ++i)
{
items.push_back(Factory.create<UIntConcrete>(i, tvr::test::factory::eDerived));
}
items.push_back(Factory.create<DoubleConcrete>(4.5, tvr::test::factory::eDerived));
items.push_back(Factory.create<StringConcrete>(std::string("Hi there!"), tvr::test::factory::eDerived));
iterate_collection DoThem;
DoThem(items);
return 0;
}
}
}
int main(int argc, const char* argv[])
{
tvr::test::test();
}
output
Doing something, like printing _item as "This is just some class.".
Doing something, like printing _item as "5".
Doing something, like printing _item as "6".
Doing something, like printing _item as "4.5".
Doing something, like printing _item as "Hi there!".
This uses a combination of templates, function overloading, and tagging through enums to help create a flexible factory class that doesn't require knowing much about the individual classes it instantiates, to include templated concrete classes as the OP asked about.
The 'eDerived' tag (in the form of an enum) tells the compiler to use the version of the factory's create function that takes a class like the template_derived class, which has a function that allows me to assign data to one of its members. As you can tell from the way I ordered the headers in main.cpp, the factory doesn't know anything about template_derived. Neither does the function calling the base class's virtual function (do_something). I think this is what the OP wanted, but without having to add a various create functions within every class that this factory might generate.
I also showed how one doesn't have to explicitly create functions for each class the factory should create. The factory's overloaded create functions can create anything derived from the base class that matches the appropriate signature.
I didn't do an extensive performance analysis on this code, but I did enough to see that the majority of the work happens in the streaming operator. This compiles in about 1 second on my 3.30Ghz quad core machine. You might need to experiment with more robust code to see how badly it might bog down the compiler, if much at all.
I've tested this code in VC++ 2015, although it probably works in other compilers pretty easily. If you want to copy this, you'll need to add your own guard headers. In any event, I hope this is useful.
You could use explicit template instanciation. Trying to call the factory method with a template parameter not explicit instanciated will give you a linker error. Note the explicit template instanciation in MyFactory.cpp
template AbstractBaseClass* MyFactory::Create(int input);
All put together looks like this (I removed shared_ptr for the sake of simplicity):
Main.cpp:
#include "AbstractBaseClass.h"
#include "MyFactory.h"
//we do not need to know nothing about concreteclass (neither MyFactory.h includes it)
int main()
{
MyFactory f;
AbstractBaseClass* ab = f.Create(10);
ab = f.Create(10.0f);
return 0;
}
MyFactory.h:
#include "AbstractBaseClass.h"
class MyFactory
{
public:
template<class T>
AbstractBaseClass* Create(T input);
};
MyFactory.cpp:
#include "MyFactory.h"
#include "ConcreteClass.h"
template<class T>
AbstractBaseClass* MyFactory::Create(T input) {
return new ConcreteClass<T>(input);
}
//explicit template instanciation
template AbstractBaseClass* MyFactory::Create(int input);
//you could use as well specialisation for certain types
template<>
AbstractBaseClass* MyFactory::Create(float input) {
return new ConcreteClass<float>(input);
}
AbstractBaseClass.h:
class AbstractBaseClass{};
ConcreteClass.h:
#include "AbstractBaseClass.h"
template<class T>
class ConcreteClass : public AbstractBaseClass
{
public:
ConcreteClass(T input) : data(input) {}
private:
T data;
};
You're looking for the "PIMPL" idiom. There's a good explanation at Herb Sutter's GOTW site
It can't be done because ConcreteClass is a template, that means you need the complete implementation available at compile time. Same reason why you can't precompile templates and have to write them all in header files instead.