テンプレートの実装はヘッダに書かないといけない

ここ10年ほどC++から離れていたので最近学びなおしをしている。

C++にはテンプレートという機能があるが、
これを学びなおすべくテスト用のクラスをテンプレートを使い実装してみた。

// Hoge.h
template <class T>
class Hoge
{
private:  
    T m_hoge;

public:
    T GetHoge();
    void SetHoge(T hoge);    
};
// Hoge.cpp
#include "./Hoge.h"

template< class T> 
T Hoge<T>::GetHoge()
{
     return m_hoge; 
}

template< class T> 
void Hoge<T>::SetHoge(T hoge)
{
     m_hoge = hoge;
}
// main.cpp
int main()
{
    Hoge<int> a;
    a.SetHoge(1);
    
    return 0;
}

実装が終わったので、さっそくメイクしてみたところ以下のようなエラーが出た。
どうやらコンパイルまでは通っているが、リンク時にメソッドの実態定義が見つからずにエラーになっているらしい。

c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: main.o:main.cpp:(.text+0x23): undefined reference to `Hoge<int>::SetHoge(int)'
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: main.o:main.cpp:(.text+0x30): undefined reference to `Hoge<int>::GetHoge()'
collect2.exe: error: ld returned 1 exit status
Makefile:2: recipe for target 'all' failed
mingw32-make: *** [all] Error 1

原因について調べてみるとこちらのブログで非常に参考になる内容が紹介されていた。
pknight.hatenablog.com

どうやらテンプレートを使用する場合、
実装については基本的にヘッダに書くのが流儀らしい。

ということでヘッダに定義内容を移したらすんなりリンクまで通った。

// Hoge.h
template <class T>
class Hoge
{
private:  
    T m_hoge;

public:
    T GetHoge() { return m_hoge; } // 定義もここに書く。
    void SetHoge(T hoge) { m_hoge = hoge; } // 定義もここに書く。  
};