Boost version of Loki StaticDispatcher

Hi All, I am looking to replace Loki with Boost since we use Boost for other parts of projects. Example of current situation: template<typename T> struct param_traits {}; template<> struct param_traits<long> { typedef long param_type; static param_type init() { return 0; } static bool fromString(const string &str, param_type &value, int base) { // Do conversion } static string toString(param_type &value, const string &fmt) { // Do conversion } }; template<> struct param_traits<double> { typedef double param_type; static param_type init() { return 0.0; } static bool fromString(const string &str, param_type &value, int base) { // Do conversion } static string toString(param_type &value, const string &fmt) { // Do conversion } }; Class BaseParamValue { public: virtual ~BaseParamValue() {}; virtual bool fromString(const string &str, int base = 0) = 0; virtual string toString(const string &ftm = "") = 0; static BaseParamValue *create(const string &type) { if (type == string("LONG")) { return new ParamValue<long>(); } else if (type == string("DOUBLE")) { return new ParamValue<double>(); } return 0; } }; template<typename T> class ParamValue : public BaseParamValue { public: typedef param_traits<T> traits_type; typedef typename traits_type::param_type ParamType; ParamValue() : mValue() { } ~ParamValue() {}; bool fromString(const string &str, int base) { return traits_type::fromString(str, mValue, base); } string toString(const string &fmt) { return traits_type::toString(mValue, fmt); } private: ParamType mValue; }; class Param { public: Param() : mParamValue(0) { } Param(const string &type) : mParamValue(BaseParamValue::create(type)) { } ~Param() { delete mParamValue; } private: BaseParamValue *mParamValue; }; So as you can see I store a BaseParamValue in the param class instead of making the Param class itself a template, which is not an option at the moment. I am currently using loki StaticDispatcher to up cast (I guess) to the correct templatized instance in the operations. What I am trying to get done is the following: class TestVisit { public: TestVisit(); ~TestVisit(); void visit(const ParamValue<long> &value); void visit(const ParamValue<double> &value); }; Is there a way in Boost to go from a BaseParamValue * to the actual templatized ParamValue and call the correct visit using: testVisit.visit(*mParamValue). Currently I get a compiler error saying: cannot conver parameter 1 from 'BaseParamValue' to 'const ParamValue<T> &' Sorry for the long post, thanks in advance. Glenn

Have you looked at boost::variant<>? You would need to make a few code changes: typedef boost::variant<double, long, int, float> ParamValue; After doing this, you no longer need a BaseParamValue or any inheritance at all for that matter. class Param { public: Param() : mParamValue(0) {} Param(const string& type) : mParamValue(create_param(type)) { } private: ParamValue create_param(const string& type) { if (type == "LONG") return ParamValue(0L); else if (type == "DOUBLE") return ParamValue(0.0); //etc } ParamValue mParamValue; }; class TestVisit : public boost::static_visitor<> { void operator()(double d) const { } void operator()(long l) const { } void operator(float f) const { } }; class TestVisitReturn : public boost::static_visitor<bool> { bool operator()(double d) const { return true; } bool operator()(long l) const { return true; } bool operator(float f) const { return true; } }; Alternatively, you could templatize the operator() to accept any of the types. int main(int argc, char** argv) { ParamValue value("LONG"); boost::apply_visitor(TestVisit(), value); bool result = boost::apply_visitor(TestVisitReturn(), value); }
participants (2)
-
Glenn Macgregor
-
Zachary Turner