//Sample.hpp template <typename T> void SomeFunc(T val); template <typename T> class Sample { public: void func(T val); } //Sample.cpp template<typename T> void SomeFunc(T val) { //実装 } template<typename T> void Sample<T>::func(T val) { //実装 } //明示的インスタンス化 template class Sample<int>; template class Sample<double>; template class Sample<std::string>; //ダミー関数によるインスタンス化 void Dummy() { SomeFunc<int>( 0 ); SomeFunc<double>( 0.0 ); SomeFunc<std::string>( "foo" ); }この場合,Sample.cppをコンパイルした時に,Sample<int>, Sample<double>, Smaple<std::string>は実体化される.そのため外部のファイルからでもこれらのクラスを利用することが可能である.
//definition struct hoge_concept {}; struct piyo_concept {}; struct hoge { typedef hoge_concept is_hoge; void operator()() { std::cout << "hoge" << std::endl; } }; struct piyo { typedef piyo_concept is_piyo; void operator()() { std::cout << "piyo" << std::endl; } }; template<typename hoge_type> void FuncForHoge(hoge_type h) { typedef hoge_type::is_hoge concept_check; } template<typename piyo_type> void FuncForPiyo(piyo_type h) { typedef piyo_type::is_piyo concept_check; } //Sample Usage FuncForHoge( hoge() ); //OK FuncForHoge( piyo() ); //NG: "is_hoge is not member of piyo" FuncForPiyo( hoge() ); //NG: "is_piyo is not member of hoge" FuncForPiyo( piyo() ); //OK
template<class T> struct Addable { T operator+(const T& other) { T tmp(*this); return tmp += other; } }; class Matrix3x3 : public Addable<Matrix3x3> { public: Matrix3x3 operator+=(const Matrix3x3& other); };
class virtual_base { public: virtual void Func()=0; }; class virtual_derived1 : public virtual_base { public: virtual void Func() { std::cout << "virtual_derived1" << std::endl; } }; class virtual_derived2 : public virtual_base { public: virtual void Func() { std::cout << "virtual_derived2" << std::endl; } }; void CallVirtualFunc(virtual_base& b) { b.Func(); } int main() { virtual_derived1 derived1; virtual_derived2 derived1; CallVirtualFunc(derived1); CallVirtualFunc(derived2); returnn 0; }
template <typename derived> class generic_base { public: //derivedの型にこれは確実に変換可能であるからstatic_castでよい.そのため実行時のコストはないと言える. void Func() { static_cast<derived*>(this)->Func(); } }; class generic_derived1 : generic_base<generic_derived1> { public: void Func() { std::cout << "generic_derived1" << std::endl; } }; class generic_derived2 : generic_base<generic_derived2> { public: void Func() { std::cout << "generic_derived2" << std::endl; } }; template <typename derived_class> void CallGenericFunc(generic_base<derived_class>& b) { b.Func(); } int main() { generic_derived1 d1; generic_derived1 d2; CallGenericFunc(d1); CallGenericFunc(d2); return 0; }
template<typename T> void CallDerivedFunc(T t) { t.Func(); }