On Fri, May 2, 2008 at 12:45 AM, Agustín K-ballo Bergé <kaballo86@hotmail.com> wrote:
Your first thoughts on a solution using a mpl::map are valid. All you
need to do is create a free function pointer template to wrap the calls.
The following code shows how:

#include <iostream>

#include <boost/mpl/map.hpp>
#include <boost/mpl/at.hpp>

void SetParamFloat( char* name, float value )
{
       std::cout << "SetParamFloat called: " << name << ", " << value <<
std::endl;
}

void SetParamInt( char* name, int value )
{
       std::cout << "SetParamInt called: " << name << ", " << value << std::endl;
}

void SetParamString( char* name, char* value )
{
       std::cout << "SetParamString called: " << name << ", " << value <<
std::endl;
}

template< typename T, void ( *ptr_to_function )( char*, T ) > class
free_function_ptr
{
public:
       static void call( char* name, T value )
       {
               ptr_to_function( name, value );
       }
};

typedef boost::mpl::map<
       boost::mpl::pair< float, free_function_ptr< float, SetParamFloat > >,
       boost::mpl::pair< int, free_function_ptr< int, SetParamInt > >,
       boost::mpl::pair< char*, free_function_ptr< char*, SetParamString > >
 >::type functions_map;

template < typename T > void set_param( char* name, T value )
{
       typedef boost::mpl::at< functions_map, T >::type function_;

       function_::call( name, value );
}

int main()
{
       set_param( "float", 1.3f );

       set_param( "int", 1 );

       char *text = "property value";
       set_param( "char*", text );

       return 0;
}

Running the code will output:
    SetParamFloat called: float, 1.3
    SetParamInt called: int, 1
    SetParamString called: char*, property value

I have compiled the code in MS VC++ 9 and the machine code generated is
the same as calling the actual functions directly (actually, the
provided test functions are inlined).

The shortcome of this solutions is that special care should be taken
when specifying the value. For instance, set_param( "float", 1.3 );
won't work since the value provided is a double, and there is no entry
for double at the function map. A quick (and tedious) solution would be
to add more entries to the map. Anyone can think of a better solution?

You'd think the compiler would be smart enough to implicitly call the float version, but then again who's to say it doesn't pick the integer version either?