依存名の問題 (チャットでのまとめ)

アバター
MNS
記事: 35
登録日時: 15年前

依存名の問題 (チャットでのまとめ)

投稿記事 by MNS » 14年前

具体的にはこういうコードでエラーがでる問題

CODE:

template 
class	XClass
{
	std::vector m_vec;

public:

	//m_vecの最初の要素を指すイテレータを取得
	std::vector::iterator GetBeginItr(){ return m_vec; } //エラー!!
};
もっと分かりやすくすると、こう

CODE:

template 
class	Nantoka
{
	//クラスTに定義された型typeの変数
	T::type		m_value;  //エラー!!

public:

	Nantoka(){}

};
上のコードでもエラーがでます。

これは、依存名というものの問題で、
上のNantokaクラスでいえば、typeが依存名で、
これがテンプレートクラスTに依存している、ということです。

これらのエラーは、この依存名のあいまいさから起こります。
上の例では、typeは「型」ですが、依存名は型だけでなく、変数、関数、何でもあります。

さきの例では、typeは型以外ありえませんから、コンパイラだって分かるだろうと思われるでしょうが、
次のような使い方の時、問題がおきます。

CODE:

template 
void	func()
{
	//クラスTに定義された型typeのポインタ
	T::type* local_ptr;  //エラー!!
}
これが何がまずいか、というと、
仮に、typeがstatic変数であるとすると、
T::type* loval_ptr → (T::type) × (local_ptr)
という積の式に解釈できてしまうことです。

コンパイラはどちらか判別できないので、
エラーになってしまうということでした。

これを回避するには、T::typeが型であると明示する必要があります。
それを行う演算子が"typename"演算子です。
よって、次のようになります。

CODE:

template 
class	Nantoka
{
	//クラスTに定義された型typeの変数
	typename	T::type	m_value;

public:

	Nantoka(){}

};
これで、コンパイラは自信をもって、
T::typeが型であると判別することができます。

よって、最初の例に戻ると、

CODE:

template 
class	XClass
{
	std::vector m_vec;

public:

	//m_vecの最初の要素を指すイテレータを取得
	typename std::vector::iterator GetBeginItr(){ return m_vec.begin(); }
};
というコードになります。


チャットで解決に尽力した方々 → バグさん、Chocolaさん、kerotanさん、nissyさん

参考:http://www.fides.dti.ne.jp/~oka-t/cppla ... ate-4.html
最後に編集したユーザー MNS on 2011年4月04日(月) 19:34 [ 編集 1 回目 ]

コメントはまだありません。