In this second version, the idea is to have the same function called on triggering, but with a different argument value for each case.
The class will be very similar to first version. The difference is that here, instead of storing the function in the map, we store the argument value. i.e. instead of having
std::map<KEY, FUNC>, we change to
Here is the full class. Don't forget to add the needed headers. And as usual with templated classes, this takes place in a header file.
template < typename KEY, typename FUNC, typename ARG > class SWITCH2 { public: SWITCH2() { myFunc = 0; } void Process( const KEY& key ) { assert( myFunc ); // needed ! typename std::map<KEY,ARG>::const_iterator it = myMap.find( key ); if( it != myMap.end() ) // If key exists, call function myFunc( it->second ); // with correct argument else // else, call function with myFunc( DefArg ); // default argument } void AddArgument( const KEY key, ARG value ) { myMap[ key ] = value; } void SetFunction( FUNC f ) { myFunc = f; } void SetDefault( ARG def ) { DefArg = def; } private: std::map< KEY, ARG > myMap; FUNC myFunc; // the function ARG DefArg; // default value, the type needs // a default constructor };
I removed here the uniqueness test, as it seemed less relevant in this situation. But you can write it back if needed.
Also note the 'assert()' checking, to make sure we don't call a function that hasn't been defined. You can easily replace this by some custom error handling function instead (exception, or whatever.)
And again, remember that this trick can only be used in specific cases where either you have to call different functions with the same argument, or the same function with different argument values.
Other solutions to this problem can be found (besides switching to another programming language, I mean...), you could also use function pointers, although this is less natural in C++.