C++ の typename キーワード
この記事では、C++ のキーワード typename について説明します。
キーワード typename の重要性を理解するには、修飾および依存名の重要な概念を理解する必要があります。
C++ での修飾名と非修飾名
修飾名はスコープを指定します。それをよりよく理解するために例を見てみましょう。
#include <bits/stdc++.h>
int main() { std::cout << "Hello world!" << std::endl; }
cout および endl への参照は、ここでは修飾名です。しかし、両方を using 宣言でスコープに入れると、つまり、using namespace std で、それ自体で cout を使用すると、std::がないため、unqualified 名になります。
C++ での依存名と非依存名
依存名は、テンプレートパラメーターに依存する名前です。
それをよりよく理解するためにサンプルコードを見てみましょう。
template <class T>
class MyClass {
int i;
vector<int> vi;
vector<int>::iterator vitr;
T t;
vector<T> vt;
vector<T>::iterator viter;
}
最初の 3つの宣言は、テンプレート宣言時にタイプがわかっているため、非依存名として知られています。
一方、2 番目の宣言は T、vector<T> および vector<T>::iterator で、これらはテンプレートパラメーターの T に依存しているため、インスタンス化の時点まで型がわからない依存した名前です。
C++ での typename キーワードの使用
原則として、typename キーワードは、タイプを参照する修飾名または従属名の前に使用する必要があります。
そのため、キーワード typename が導入され、後続の識別子が静的メンバー変数ではなくタイプであることを指定します。
class A {
public:
typedef int myPtr;
};
template <class T>
class myClass {
public:
typename T::SubType* myPtr;
}
上記のコードで、typename キーワードは、SubType がクラス T のタイプであることをコンパイラーに通知します。つまり、ポインターmyptr は T::SubType のタイプです。
typename キーワードがない場合、SubType は静的メンバーと見なされ、コンパイラーは、タイプ T の SubType とポインターmyptr の乗算として評価します。
T::SubType * myptr //compiler will think it's multiplication
もし、上記のコードでキーワード typename を使用しなかった場合、コンパイラは T::SubType が型名なのか T のスタティックメンバなのか分からないため、コンパイル時のエラーとなります。
