my_class.h
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
// 関数テンプレート https://www.qoosky.io/techs/22b50b7062 と同様、
// テンプレートは通常ヘッダファイルにすべてを記述する必要があります。
// ヘッダファイルでの using 使用は好ましくないため std::cout 等とします。
#include <iostream>
template <typename MY_TYPE>
class MyClass
{
public:
MyClass(MY_TYPE val);
MyClass(const MyClass& other); // コピーコンストラクタ
public:
void Say() const;
private:
MY_TYPE m_val;
};
template <typename MY_TYPE>
MyClass<MY_TYPE>::MyClass(MY_TYPE val) :
m_val(val)
{
// m_val = val; // とするよりもシンプル: https://www.qoosky.io/techs/3fef7fa668
}
template <typename MY_TYPE>
MyClass<MY_TYPE>::MyClass(const MyClass& other)
// MyClass<MY_TYPE>::MyClass(const MyClass<MY_TYPE>& other) // の省略形
// ↑コンパイラが古くなければ「MyClass<MY_TYPE>」以降の「MyClass」は
// 「MyClass<MY_TYPE>」と解釈されます。
{
// コピーするだけの例
m_val = other.m_val;
}
template <typename MY_TYPE>
void MyClass<MY_TYPE>::Say() const
{
std::cout << "MyClass::Say, " << m_val << std::endl;
}
#endif // #ifndef MY_CLASS_H_
main.cpp
#include <iostream>
#include "my_class.h"
using namespace std;
int main() {
// 関数テンプレートと異なり、型の自動判別は困難な場合
// が多く、無効化されています。明記する必要があります。
MyClass<int> obj(1);
MyClass<int> objCopied = obj;
obj.Say();
objCopied.Say();
return 0;
}
関数テンプレートとは異なり、クラステンプレートにはテンプレート引数の既定値を記述できます。
my_class.h
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
#include <iostream>
template <typename MY_TYPE = char>
class MyClass
{
public:
MyClass(MY_TYPE val);
public:
void Say() const;
private:
MY_TYPE m_val;
};
template <typename MY_TYPE>
MyClass<MY_TYPE>::MyClass(MY_TYPE val) :
m_val(val)
{
}
template <typename MY_TYPE>
void MyClass<MY_TYPE>::Say() const
{
std::cout << "MyClass::Say, " << m_val << std::endl;
}
#endif // #ifndef MY_CLASS_H_
main.cpp
#include <iostream>
#include "my_class.h"
using namespace std;
int main() {
MyClass<> ch(97);
MyClass<int> i(97);
ch.Say(); //=> MyClass::Say, a
i.Say(); //=> MyClass::Say, 97
return 0;
}
なお、デフォルトテンプレート引数が複数ある場合は以下のように既出のテンプレート引数の値に依存させることができます。
template <typename MY_TYPE = char, typename MY_TYPE_2 = MY_TYPE>
template < typename MY_TYPE = char, typename MY_TYPE_2 = MyOtherClassTemplate<MY_TYPE> >
その際、後者の例では ">" と ">" の間にスペースを入れて、コンパイラが演算子 ">>" と区別できる状態にする必要があります。
my_class.h
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
#include <iostream>
template <template <typename, typename> class MY_TEMPL>
class MyClass
{
public:
void SetShow();
private:
MY_TEMPL< int, std::allocator<int> > m_val;
};
template <template <typename, typename> class MY_TEMPL>
void MyClass<MY_TEMPL>::SetShow()
{
m_val.push_back(0);
m_val.push_back(1);
std::cout << "MyClass::SetShow(" << m_val.size() << ")" << std::endl;
}
#endif // #ifndef MY_CLASS_H_
main.cpp
#include "my_class.h"
#include <iostream>
#include <vector> // https://www.qoosky.io/techs/62846dd250
#include <deque> // https://www.qoosky.io/techs/9828f24f38
using namespace std;
int main() {
MyClass<vector> objV;
MyClass<deque> objD;
objV.SetShow(); //=> MyClass::SetShow(2)
objD.SetShow(); //=> MyClass::SetShow(2)
objV.SetShow(); //=> MyClass::SetShow(4)
objD.SetShow(); //=> MyClass::SetShow(4)
return 0;
}
my_class.h
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
#include <iostream>
#include <algorithm>
template <int N> // double など小数は指定できない仕様 (環境によってはコンパイルできてしまう)
class MyClass
{
public:
static const int SIZE = N; // 静的メンバ定数 https://www.qoosky.io/techs/fc41205299
public:
MyClass();
public:
void Show(int i) const;
private:
int m_intarr[SIZE];
};
template <int N>
MyClass<N>::MyClass()
{
std::fill_n(m_intarr, SIZE, 0);
}
template <int N>
void MyClass<N>::Show(int i) const
{
std::cout << m_intarr[i] << std::endl;
}
#endif // #ifndef MY_CLASS_H_
main.cpp
#include "my_class.h"
#include <iostream>
using namespace std;
int main() {
MyClass<8> obj;
for (size_t i = 0, size = MyClass<8>::SIZE; i < size; ++i) {
obj.Show(i);
}
cout << MyClass<8>::SIZE << endl; //=> 8
cout << MyClass<16>::SIZE << endl; //=> 16
return 0;
}