By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,797 Members | 1,794 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,797 IT Pros & Developers. It's quick & easy.

Having a design program

P: n/a
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
Jul 23 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a
REH wrote:
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


Variant records are such the nightmare.

The case in point: assignment.
One has to allow assignment between variant records of
the same type, but not allow assignment between variant
records of different types.

Last time I researched this, I was using the Visitor
pattern along with double-dispatch to handle type safe
assignment. I want to be able to assign generic "fields"
to each other without knowing the types. {This occurs
when copying generic records.} Such the nightmare.

My solution was to have a base class which defines
operator=() as throwing an exception. Descendant
classes are encouraged to provide their own assignment
operators. Any base classes in the middle must throw
exceptions for their assignment operators.

This was just assignment. Equality is another headache.
And you want type conversion. Don't come walking my
way with this.

Perhaps remembering Scott Meyer's discussion that
public functions may increase encapsulation will help.
I.e. Function(MyObject& obj) vs obj.Function().
--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
Jul 23 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.