From: Maxim Yegorushkin (maxim.yegorushkin_at_[hidden])
Date: 2006-04-21 03:28:24


Chris Uzdavinis wrote:
> Hi, I have an idea of something, and am not sure if Boost provides it.
> In short, I'd like an adapter object that "wraps" a boost::function
> object, and changes the interface such that all the N arguments are
> taken as strings, automatically converted (using lexical_cast?) to the
> proper types, and then invoke the boost::function object passsing in
> those parameters.
>
> For example, I envision something like this:
>
> #include "boost/function.hpp"
> #include <iostream>
>
> void func(int i, char c)
> {
> std::cout << "f called with " << i << " and " << c << std::endl;
> }
>
>
> int main()
> {
> boost::function<void(int, char)> f;
> f = &func;
>
> // I'm wanting something like this.
> boost::function_string_adapter str_f(f);
>
> // call func() but pass string args instead of int,char
> str_f("123", "x"); // invokes f(123i, 'x')
> }
>
> The magic is that boost::function knows the proper types, so the
> adapter could ask it to what type each string needs to be converted,
> then it could do a lexical_cast to get the value.

Can it be done in a straightforward way?

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/lexical_cast.hpp>
#include <string>
#include <iostream>

struct caster
{
     std::string s;
     template<class T>
     operator T() const { return boost::lexical_cast<T>(s); }
     caster(std::string const& s) : s(s) {}
     caster(char const* s) : s(s) {}
};

void f(int i, double d)
{
     std::cout << i << char(0xa) << d << char(0xa);
     // sorry, my back-slash key does not work
}

int main()
{
     boost::function<void(caster, caster)> g(f);
     g("123", "3.13");
}

> My motivation for wanting this is to implement a "simple" command
> interpreter for a socket-based administrative interface. I
> pre-register a bunch of function objects, then whenever someone sends
> a command down the socket, it arrives as a string. The function
> object is looked up by name, and then the call-operator is invoked
> given the string arguments. Internally, the proper string-to-type
> converstions occur, and the boost::function is called with those
> values. (If the conversion fails, an exception would be perfectly
> reasonable.)

Don't you have to tokenize the input first? While doing so you might
parse it as well.