テンプレート引数の記述を省略する

ロベールのC++入門講座 09-07

タイトルがちょっとわかり辛いですが、例を見ればすぐわかると思います。

まず以下の処理を見てください。

template<class T>
class CSample {
public:
    CSample<T>& operator=(const CSample<T>& obj) {
        // 中身は適当。とりあえず自分自身を返しておく
        return *this;
    }
};

戻り値や引数に自分自身のクラスを指定する場合、

CSample<T>

といったようにをつけて書くのですが、実はの部分は省略が可能なのです。

template<class T>
class CSample {
public:
    CSample& operator=(const CSample& obj) {
        // 中身は適当。とりあえず自分自身を返しておく
        return *this;
    }
};

省略してもコンパイルは通ります。

これはこのクラスがtemplateであることが既にハッキリしているので省略が可能となります。

しかしinlineせずに定義した場合は注意が必要です。

#include <iostream>

template<class T>
class CSample {
public:
    // 宣言だけ
    CSample& operator=(const CSample& obj);
};

// 定義する
template<class T>
CSample<T>& CSample<T>::operator=(const CSample& obj) {
    return *this;
}

この場合、が省略できるのは引数の部分だけとなります。

何故かというと、まず「CSample::operator=」はをつけないとCSampleの解釈ができないのです。CSampleはクラステンプレートであってクラスではないのでCSampleといったように明示的書いてやる必要があります。

そして一度CSampleと書けば以降のCSampleはクラステンプレートであるということがハッキリするので引数のCSampleにはを省略することができます。

同じ理由から戻り値のCSampleはまだCSampleがまだハッキリしていない状態なのでCSampleを書かないといけないようです。

省略可能であることはわかりましたが、色々と面倒臭いので基本的にはを書いておいたほうが安全だとは思います。