Hello All,
I am planning a project. It's in a design stage. For that project,
I need a generic value type.
By that I mean, that it should be possible to construct that type from
any (some reasonable set) other type and be castable to any such type,
perhaps using dynamic_cast method like RefPtr does. This cast or method
would throw bad_cast, if the object actualy contained incompatible type.
What I want is to allow:
void foo(int x);
Value a = 1;
Value b = "string";
foo(a); // OK, a is an integer
foo(b); // throws bad_cast, because it's not a number.
Since I will be passing that type to Gtkmm calls a lot, I want it
convertible to Glib::ValueBase. Thus I thought that it could in fact be
based on the existing Glib::Value infrastructure.
I thought about something like this:
class Value : Glib::ValueBase {
protected:
void swap(Value &that)
{
GValue tmp;
tmp = that.gobject_;
that.gobject_ = this->gobject_;
this->gobject_ = tmp;
}
public:
// some not-interesting default constructor
// template constructor from anything
template <class VT> Value(VT &val)
{
Glib::Value<VT> tmp;
tmp.set(val);
this->swap(tmp);
}
template <> Value(Glib::ValueBase &val) :
Glib::ValueBase(val)
{};
// operator= using above constructors and swap
// And now the highest madness! The cast operators!
// FIXME This won't work. It does not do sane checking.
template <class VT> operator VT()
{
Glib::Value<VT> tmp;
tmp = *this; // FIXME This does not exist!
return tmp.get();
}
// Perhaps some more operations should be defined too, like
// a stringification operation for printing and such.
}
The FIXME denotes the point where I am in trouble. What I need is an
operation, that would copy one Glib::ValueBase to a Glib::ValueBase
descendant calling g_value_transform and throwing a bad_cast exception
if it returns NULL.
I think it should be possible to implement the operation here -- after
all, it inherits Glib::ValueBase and thus has access to it's guts. I am
nowever not completely sure HOW it should be done. What are your
opinions on this?
Also it does not work with enums and flags, because enums are
Glib::Value_Enum and flags are Glib::Value_Flags. It would suffice to
use static constructor methods for enums. Does anyone have a better
idea?
Since I don't have much experience with C++, it's quite possible that
there are other bugs too. Please correct me if I am wrong somewhere.
-------------------------------------------------------------------------------
Jan 'Bulb' Hudec <bulb ucw cz>
Attachment:
signature.asc
Description: Digital signature