funnyクラスを作ってみた。その2
funnyの色々な使い方。
// メンバ関数を呼び出す。 template <class T,class U,class V,class W> class speak_type:public U { public: void speak() const { static_cast<const T*>(this)->data()->speak(); } struct interface { virtual void speak() const=0; }; }; class dog { public: void speak() const { std::cout << "わん\n"; } }; class cat { public: void speak() const { std::cout << "にゃ〜\n"; } }; int main() { dog pochi; cat tama; funny<speak_type> pet; // メンバ関数speak()の呼出しが可能 pet = pochi; pet.speak(); pet = tama; pet.speak(); return 0; }
// キャストなしで出力可能にする。 template <class T,class U,class V,class W> class output_type:public U { public: friend std::ostream& operator<<(std::ostream& os, const T& x) { return x.data()->print(os); } std::ostream& print(std::ostream& os) const { return os << *(static_cast<const T*>(this)->data()); } struct interface { virtual std::ostream& print(std::ostream& os) const = 0; }; }; int main() { funny<output_type> x; x = 1; std::cout << x << std::endl; x = 3.1415; std::cout << x << std::endl; return 0; }
//加算可能にする。 template <class T,class U,class V,class W> class add_type:public U { public: V& operator+=(const V& x) { static_cast<T*>(this)->typecheck(static_cast<const T&>(x)); *(static_cast<T*>(this)->data())+=*(static_cast<const T&>(x).data()); return *static_cast<T*>(this); } friend T operator+(const T& x, const T& y) { T tmp(x); return tmp+=y; } struct interface { virtual typename T::funny_imp_base& operator+=(const typename T::funny_imp_base&) = 0; }; }; int main() { funny<add_type> x(1),y(2); std::cout << int(x+y) << std::endl; return 0; }
// 型Sとの加算を可能にする。 template <class S> class Add { public: template <class T,class U,class V,class W> class type:public U { public: W operator+(const S& x) const { return *(static_cast<const T*>(this)->data())+x; } friend W operator+(const S& x,const T& y) { return y.data()->addr(x); } W addr(const S& x) const { return x+*(static_cast<const T*>(this)->data()); } struct interface { virtual W operator+(const S&) const = 0; virtual W addr(const S&) const = 0; }; }; }; int main() { funny<Add<int>::type> a(3.4); std::cout << double(a+4) << std::endl; }