enum { success, failure, /* more status results */ } status;// Functions to read to and write to void pointers:typedef status(*set_func)(string const& src, void* dest);typedef status(*get_func)(string& src, void const* dest);// A value that knows how to be read from and written to:struct console_value { void* v; set_func set; get_func get; console_value(void* v_, set_func set_, get_func get_ ): v(v_), set(set_), get(get_) {}};// the names of the user-modifiable values:typedef std::map< string, console_value > value_map;// you have to write the actual string <-> value conversionsstatus parse_value( string const& value, double& d );status parse_value( string const& value, int& d );status parse_value( string const& value, string& d );// etc.status print_value( string& result, double d );status print_value( string& result, int d );status print_value( string& result, string const& d );// etc.// helper code:template<typename T>struct setter_getter {private: static status set_data( string const& value, T* t ) { return parse_value( value, *t ); } static status get_data( string& result, T const* t ) { return print_value( result, *t ); }public: static status set_helper( string const& value, void* v ) { return set_data( value, reinterpret_cast<T*>(v) ); } static status get_helper( string& value, void const* v ) { return set_data( value, reinterpret_cast<T const*>(v) ); }};template <typename T>void Bind(value_map& vm, string & const name, T *ptr){ typedef setter_getter<T> set_get; console_value cv( ptr, set_get::set_helper, set_get::get_helper ); vm[name] = cv;}
and voila. You just have to pass pointers to the data.
You can even have read-only parameters with very little work, or parameters that are not strictly variables.