
Hello - I want to do type conversions (checked at compile-time) using boost::variant. So I naively made a 'convert' visitor, which has designed to (hopefully) safely convert the variant value to another type (eg: a client might try to assign the variant's int value to an unsigned short). For instance: typedef boost::variant < std::string, int, double > ParamValue; // ----- ConvertParamValueVisitor //T is the type which will be assigned the variant's value //V is the Variant/Visitor template<typename T> struct ConvertParamValueVisitor<T> { typedef ConvertParamValueVisitor self; typedef void result_type; self( T*& val ) : value_(val) {} template<typename V> result_type operator()( const V& v, typename boost::enable_if<TypeTraits::is_arithmetic<V> >::type* dummy = 0 ) const { *value_ = boost::numeric_cast<T>(v); } template<typename V> result_type operator()( const V& v, typename boost::enable_if<TypeTraits::is_string<V> >::type* dummy = 0 ) const { *value_ = v; } private: T*& value_; }; It seems boost::variant will instantiate all members for all variant types, even the ones I try to suppress using enable_if. To work around this, I've tried various things, like specializing ConvertParamValueVisitor based on T, using lazy_enable_if, etc. Here's one attempt: // ----- ConvertParamValueVisitor //T is the type which will be assigned the variant's value //V is the Variant/Visitor //not implemented template<typename T, class Enable = void> struct ConvertParamValueVisitor; //ConvertParamValueVisitor int, double: use numeric cast template<typename T> struct ConvertParamValueVisitor<T, typename boost::enable_if<TypeTraits::is_arithmetic<T> >::type
{ typedef void result_type; typedef ConvertParamValueVisitor self; self( T*& val ) : value_(val) {} template<typename V> result_type operator()( const V& val, typename boost::enable_if<TypeTraits::is_arithmetic<V> >::type* dummy = 0 ) const { *value_ = boost::numeric_cast<T>(val); } //not implemented template<typename V> result_type operator()( const V& val, typename boost::enable_if<TypeTraits::is_string<V> >::type* dummy = 0 ) const; private: T*& value_; }; //ConvertParamValueVisitor string template<typename T> struct ConvertParamValueVisitor<T, typename boost::enable_if<TypeTraits::is_string<T> >::type > { typedef void result_type; typedef ConvertParamValueVisitor self; self( T*& val ) : value_(val) {} //not implemented template<typename V> result_type operator()( const V& val, typename boost::enable_if<TypeTraits::is_arithmetic<V> >::type* dummy = 0 ) const; template<typename V> result_type operator()( const V& val, typename boost::enable_if<TypeTraits::is_string<V> >::type* dummy = 0 ) const { *value_ = val; } private: T*& value_; }; Is there any way to get something like this to work? Am I simply mis-applying boost::variant? I could of course just throw an exception in the unsupported/not implemented methods above, but I'd like this checked at at compile time if possible. (note that my question is generally applicable to visitors, not just to boost::variant). thanks! --craig __________________________________ Do you Yahoo!? Yahoo! Mail - 50x more storage than other providers! http://promotions.yahoo.com/new_mail