37章 テンプレートの特殊化
http://www.geocities.jp/ky_webid/cpp/language/037.html
基本的にはテンプレート使いたいけど、ある型のときだけ別の処理にしたいというときに使えるのがテンプレートの特殊化という機能です。
#include <iostream> using namespace std; template<class T> class CSample { public: CSample(T t) : m_t(t) {} T Get() { return m_t; } private: T m_t; }; template<> class CSample<int> { public: CSample(int t) : m_t(t) {} int Get() { return m_t + 100; } private: int m_t; }; int main () { CSample<long> obj1(100); CSample<int> obj2(100); cout << obj1.Get() << endl; cout << obj2.Get() << endl; // intの時だけ100足される return 0; }
$ main 100 200
うまくいってますね。
しかしこれ、場合によってはかなりのコードの二重化が発生しそうです。
しかもテンプレートなので共通化もできそうにないですし。
ふと思ったんですが、上記のような処理であれば、オーバーライドでできないもんでしょうか?
やはりテンプレートの定義と、普通の型の定義は両立できない?
一応試してみました。
#include <iostream> using namespace std; template<class T> class CSample { public: CSample(T t) : m_t(t) {} T Get() { return m_t; } int Get() { return m_t + 100; } // intの時だけ別処理 private: T m_t; }; int main () { CSample<long> obj1(100); CSample<int> obj2(100); cout << obj1.Get() << endl; cout << obj2.Get() << endl; return 0; }
コンパイルエラーがどっさりorz
やはり無理なんですね。
次に、テンプレートの特殊化は当然関数にも適応できます。
#include <iostream> using namespace std; template<class T> void foo (T t) { cout << t << endl; } template<> void foo<int>(int t) { cout << t+100 << endl; } int main () { foo("abc"); foo(100); return 0; }
$ main abc 200
このようにintの時だけ100足されてますね。
さて、上記では
template<> void foo<int>(int t)
と書きましたが、実はもう少し省略できます。
template<> void foo(int t)
テンプレートの特殊化であることはわかっているのでfooの後ろの