I'm implementing code to exchange TCP messages and I came across an interesting approach to message construction in this stackoverflow posting. It uses a factory pattern in which the type of object to be created is registered with the factory. The registration function is a member template whose template parameter is the type of object to create but not an argument to the function itself (which is a corresponding integer identifier).
/**
* A class for creating objects, with the type of object created based on a key
*
* @param K the key
* @param T the super class that all created classes derive from
*/
template<typename K, typename T>
class Factory {
private:
typedef T *(*CreateObjectFunc)();
/**
* A map keys (K) to functions (CreateObjectFunc)
* When creating a new type, we simply call the function with the required key
*/
std::map<K, CreateObjectFunc> mObjectCreator;
/**
* Pointers to this function are inserted into the map and called when creating objects
*
* @param S the type of class to create
* @return a object with the type of S
*/
template<typename S>
static T* createObject(){
return new S();
}
//skip a bunch of code...
public:
/**
* Registers a class to that it can be created via createObject()
*
* @param S the class to register, this must ve a subclass of T
* @param id the id to associate with the class. This ID must be unique
*/
template<typename S>
void registerClass(K id){
if (mObjectCreator.find(id) != mObjectCreator.end()){
//your error handling here
}
/*Note: I removed the explicit template parameters from the
*call to std::make_pair() in the original code referenced in
*text above since it caused complilation errors. */
mObjectCreator.insert( std::make_pair(id, &createObject<S> ) );
}
}
I don't see how the type to be created () is registered since it's type is not an argument to the registration function and therefore cannot be deduced from those arguments. Is this a problem in the code or do I need to declare that function in some way?
` causes `createObject– Igor Tandetnik Jul 08 '18 at 14:40` to be instantiated. For each type `S` passed as a template parameter of `registerClass`, a new function `createObject` is stamped out from template definition, and the address of this function stored, to be called later. The type is in effect embedded in the body of the corresponding instance of `createObject` function. This technique is known as "type erasure" (you can access something that knows about type `S` via something - here, a function pointer - that doesn't mention type `S` in any way; the type has been "erased").) );` - drop explicit template arguments for `make_pair`; they are wrong. With that, [your code compiles](http://rextester.com/EUBBL19852)– Igor Tandetnik Jul 08 '18 at 16:37