忘记叫什么设计模式了,大概是这样:
struct Object
{
virtual string GetType() const { return typeid(*this).name(); }
virtual string ToString() const { return GetType(); }
virtual ~Object() { }
};
struct ValueType { };
//This makes a value type an Object.
//Specialize this template if a value
//type is implementing an interface.
template <class T>
struct RefValueType : Object, T
{
static_assert(std::is_base_of<ValueType, T>::value, "T must be value type.");
template <class...TArgs>
RefValueType(TArgs &&...args) : T(args...) { }
// Use using T::T; when mingw supports that.
virtual ~RefValueType() { }
virtual string ToString() const { return T::ToString(); }
virtual string GetType() const { return T::GetType(); }
};
struct IFormattable
{
virtual string ToString(string format) const = 0;
virtual ~IFormattable() { }
};
struct Int32 : ValueType
{
//make this struct looks like a int.
string GetType() const { return "Int32"; }
string ToString() const { /*normal tostring*/ }
//implementing IFormattable? Yes, but implicitly.
string ToString(string format) const { /*tostring w/ format*/ }
private: int value;
};
template <>
struct RefValueType<Int32> : Object, Int32, IFormattable
{
template <class...TArgs>
RefValueType(TArgs &&...args) : Int32(args...) { }
virtual string GetType() const { return Int32::GetType(); }
virtual string ToString() const { return Int32::ToString(); }
virtual string ToString(string format) const { return Int32::ToString(format); }
virtual ~RefValueType() { }
};
//When boxing a value type "vt",
//a RefValueType<decltype(vt)> is created on gc as a copy.
//This saves space for a value type object created on
//stack(you don't need a vtable -w-).
struct Object
{
virtual string GetType() const { return typeid(*this).name(); }
virtual string ToString() const { return GetType(); }
virtual ~Object() { }
};
struct ValueType { };
//This makes a value type an Object.
//Specialize this template if a value
//type is implementing an interface.
template <class T>
struct RefValueType : Object, T
{
static_assert(std::is_base_of<ValueType, T>::value, "T must be value type.");
template <class...TArgs>
RefValueType(TArgs &&...args) : T(args...) { }
// Use using T::T; when mingw supports that.
virtual ~RefValueType() { }
virtual string ToString() const { return T::ToString(); }
virtual string GetType() const { return T::GetType(); }
};
struct IFormattable
{
virtual string ToString(string format) const = 0;
virtual ~IFormattable() { }
};
struct Int32 : ValueType
{
//make this struct looks like a int.
string GetType() const { return "Int32"; }
string ToString() const { /*normal tostring*/ }
//implementing IFormattable? Yes, but implicitly.
string ToString(string format) const { /*tostring w/ format*/ }
private: int value;
};
template <>
struct RefValueType<Int32> : Object, Int32, IFormattable
{
template <class...TArgs>
RefValueType(TArgs &&...args) : Int32(args...) { }
virtual string GetType() const { return Int32::GetType(); }
virtual string ToString() const { return Int32::ToString(); }
virtual string ToString(string format) const { return Int32::ToString(format); }
virtual ~RefValueType() { }
};
//When boxing a value type "vt",
//a RefValueType<decltype(vt)> is created on gc as a copy.
//This saves space for a value type object created on
//stack(you don't need a vtable -w-).