|
Boost : |
From: craig perras (craigp98072_at_[hidden])
Date: 2004-06-30 13:57:37
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk