14.6.1/1 の言語標準で明示的に指定されています。
クラス テンプレートのスコープ内で、テンプレートの名前が修飾されておらず、< が続いていない場合、テンプレートの名前の後に <> で囲まれたテンプレート パラメータが続いたものと同等です。
これは、標準の後のバージョンで (「注入されたクラス名」の概念を通じて) 言い直されましたが、ポイントは、この動作がドキュメントで明示的に綴られていることです。
質問の 2 番目の部分に答えるために、この規則は、クラス外のメソッド定義を記述するときのパラメーター宣言にも適用されますが、戻り値の型宣言には適用されません。たとえば、このコードはOKです
template <typename T> struct S {
S foo(S);
};
template <typename T> S<T> S<T>::foo(S s) {
/* whatever */
}
<T>
ただし、メソッドの定義で戻り値の型からビットを削除することはできません。<T>
(また、メソッドの修飾名から削除することはできません。)
具体的には、コンストラクター<T>
に関しては、クラスの完全な名前 (を含む) を使用する必要があります<T>
が、コンストラクター自体の名前には使用しないでください。したがって、あなたの場合のクラス外定義の最短形式は次のようになります
template <typename T> Wrapper<T>::Wrapper(const Wrapper& w) : t_(w.t_)
{
}
<T>
コンストラクタ名にビットを追加したい場合でも、ビットを追加できないことに注意してください。
template <typename T> Wrapper<T>::Wrapper<T>(const Wrapper& w)
^ ERROR !!!
PS この最後の主張については、さらなる調査が必要です。Comeau Online コンパイラはエラーと判断しますが、GCC は問題ないと判断します。後で戻ってきます。
PPS MSVC++ 2005 のコンパイラは、後者の宣言について警告を表示します
warning C4812: obsolete declaration style: please use 'Wrapper<T>::Wrapper' instead
面白い...