Much depends on the circumstances, but most often the solution is probably to use a static map instance for the factory. If the key type of map is a small integer value, as in your example, a "map" can be nothing more than an array of C styles:
static Base* foo( int bar ) { static Base* (*factories[])() = [ &aFactory, &bFactory ]; return bar >= 0 && bar < size( factories ) ? (*factories[bar])() : baseFactory(); }
More generally, you can use std::map (for any conceivable type), and you can map static instances of factory, not factory functions, if different keys should lead to the same type, but with different arguments.
EDIT:
Some suggestions for improving the Dictionary::Call function:
Base* Dictionary::Call( int i ) const { std::map<int, FunctionPointer>::const_iterator entry = fmap.find( i ); return entry == fmap.end() ? new Base() : (this->*(entry->second))(); }
I made the const function, since it does not change anything, and most imperceptibly, I use std::map<>::find so as not to insert extra entries into the map if the object is not already there.
And since I am adding const, you will need to update LurieE:
typedef Base* (Dictionary::*FunctionPointer)() const;
Another suggestion: if the factory functions do not need Dictionary access, make them static. The syntax is much simpler (and this will probably also improve performance). static changes typedef again:
Also: in the constructor new A() not a function to build a new object. Maybe something make this easier in C ++ 11 (between lambda and std::function ), but otherwise you still have to write each of the factory functions manually. Or you can use the template:
template <typename Target> Base* construct() const { return new Target(); } Dictionary() { fmap.insert( std::make_pair( 0, &Dictionary::construct<A> ) );
Or, if you make them static:
typedef Base* (*FunctionPointer)(); // ... template <typename Target> static Base* construct() { return new Target(); } Base* Dictionary::Call( int i ) const { std::map<int, FunctionPointer>::const_iterator entry = fmap.find( i ); return entry == fmap.end() ? new Base() : (*entry->second)(); }
You will notice how static simplifies declarations (and calling a function through a pointer - a pointer to a member function has become a simple pointer to a function).