R
REH
As I posted last week, I updated my C++ library to include a variant record
class. While using it in some code, I'm finding it would be convenient to
have a method that would basically say to the class object, "I don't care
what type of object you currently contain, but I know it is convertible to
T, so do it." Basically, I want a class member like:
template<class T>
T convert_to() const;
So, if I had a variant_record defined as such:
typedef variant_record<short, int, long> record;
record r = 1;
regardless of what it contains, I could say:
long v = r.convert_to<long>();
Currently, I would have to do something like this:
switch(r.get_type())
{
case record::type<short>::id:
v = r.get<short>();
break;
case record::type<int>::id:
v = r.get<int>();
break;
case record::type<long>::id:
v = r.get<long>();
break;
}
Now, I know in this case, I could simplify thing by just storing short and
int values in a long, but this is just an example.
I thought about this implementation:
template<class T>
T convert_to() const
{
switch (m_type)
{
case t1: return T(get<T1>());
case t2: return T(get<T2>());
case t3: return T(get<T3>());
case t4: return T(get<T4>());
// etcetera
}
The problem with this is the compiler would complain for the cases were one
of the types has no conversion to T.
I also thought about having each case call a static member of a template
structure with a bool template parameter and specialize on false if there is
not conversion. Something like:
template<class To, class From, bool B>
struct convert_helper {
static To convert(const From& f) {return To(f);}
};
template<class To, class From>
struct convert_helper<To, From, false> {
static To convert(const From& f) {throw invalid_variant_access();}
};
And then create a template "is_convertible" to determine if a cast is
possible. The problem here is (I think) it is not possible for
"is_convertible" to detect explicit casts, only implicit ones.
Anyone have any ideas how I can accomplish this?
Thanks,
REH
class. While using it in some code, I'm finding it would be convenient to
have a method that would basically say to the class object, "I don't care
what type of object you currently contain, but I know it is convertible to
T, so do it." Basically, I want a class member like:
template<class T>
T convert_to() const;
So, if I had a variant_record defined as such:
typedef variant_record<short, int, long> record;
record r = 1;
regardless of what it contains, I could say:
long v = r.convert_to<long>();
Currently, I would have to do something like this:
switch(r.get_type())
{
case record::type<short>::id:
v = r.get<short>();
break;
case record::type<int>::id:
v = r.get<int>();
break;
case record::type<long>::id:
v = r.get<long>();
break;
}
Now, I know in this case, I could simplify thing by just storing short and
int values in a long, but this is just an example.
I thought about this implementation:
template<class T>
T convert_to() const
{
switch (m_type)
{
case t1: return T(get<T1>());
case t2: return T(get<T2>());
case t3: return T(get<T3>());
case t4: return T(get<T4>());
// etcetera
}
The problem with this is the compiler would complain for the cases were one
of the types has no conversion to T.
I also thought about having each case call a static member of a template
structure with a bool template parameter and specialize on false if there is
not conversion. Something like:
template<class To, class From, bool B>
struct convert_helper {
static To convert(const From& f) {return To(f);}
};
template<class To, class From>
struct convert_helper<To, From, false> {
static To convert(const From& f) {throw invalid_variant_access();}
};
And then create a template "is_convertible" to determine if a cast is
possible. The problem here is (I think) it is not possible for
"is_convertible" to detect explicit casts, only implicit ones.
Anyone have any ideas how I can accomplish this?
Thanks,
REH