#include #include #include #include #include // RTTI not required, just used for example using namespace std; /// Properties cribbed from Reece Dunn's implementation template struct property_type { typedef T value_type; typedef S subscript_type; typedef I index_type; typedef C constructor_type; }; template class aliased_property : public property_type { T* value; public: aliased_property (T& v) : value (&v) {} T get () const { return *value; } void set (const T& v) { *value = v; } }; template class value_property : public property_type { T value; public: value_property (T v = T()) : value (v) {} T get () const { return value; } void set (const T& v) { value = v; } }; template ostream& operator<< (ostream& os, const vector& v) { os << '['; typename vector::size_type len = v.size (); for (typename vector::size_type i = 0; i < len; ++i) { os << v[i]; if (i < len - 1) os << ','; } os << ']'; } // The common Wombat struct Wombat { string name; aliased_property name_p; value_property weight; value_property hometown; value_property > children; Wombat () : name ("Norman the Wombat"), name_p (name), weight (25.09), hometown ("Canberra") {} friend ostream& operator<< (ostream& os, const Wombat& w) { return os << "Wombat: " << "name=" << w.name_p.get() << " " << "weight=" << w.weight.get() << " " << "hometown=" << w.hometown.get() << " " << "children=" << w.children.get (); } // Supply visitor with the property information template void apply_visitor (V& visitor) { visitor ("name", name_p); visitor ("weight", weight); visitor ("hometown", hometown); visitor ("children", children); } }; template void print (ostream& os, const T& value) { os << value << ' '; } template<> void print (ostream& os, const double& d) { os << setprecision (15) << d << ' '; } template<> void print (ostream& os, const string& s) { os << '`' << s << "' "; } class print_property_visitor { public: template void operator () (const char* name, const T& value) const { cout << name << '[' << typeid (typename T::value_type).name() << "]="; print (cout, value.get ()); } }; int main () { Wombat w; cout << w << endl; print_property_visitor v; w.apply_visitor (v); cout << endl; }