Krótka wersja, którą należy wykonać typename X::Y
, gdy X jest lub zależy od parametru szablonu. Dopóki X nie jest znany, kompilator nie może stwierdzić, czy Y jest typem czy wartością. Musisz więc dodać typename
, aby określić, że jest to typ.
Na przykład:
template <typename T>
struct Foo {
typename T::some_type x; // T is a template parameter. `some_type` may or may not exist depending on what type T is.
};
template <typename T>
struct Foo {
typename some_template<T>::some_type x; // `some_template` may or may not have a `some_type` member, depending on which specialization is used when it is instantiated for type `T`
};
Jak SBI zwraca uwagę w komentarzach, przyczyną dwuznaczności jest Y
może być statyczny element, enum lub funkcją. Nie znamy typu X
, nie możemy powiedzieć. Standard określa, że kompilator powinien przyjąć, że jest to wartość, chyba że została wyraźnie oznaczona jako typ za pomocą słowa kluczowego typename
.
I to brzmi jak komentujących naprawdę chcesz mi wspomnieć o innej związanej sprawę także:;)
Jeśli nazwa zależna jest szablonem członek funkcja, i nazywają to z wyraźną szablonu argumentu (foo.bar<int>()
, dla przykład), należy dodać słowo kluczowe template
przed nazwą funkcji, jak w foo.template bar<int>()
.
Powodem jest to, że bez słowa kluczowego szablon, kompilator zakłada, że bar
jest wartością i chcesz wywołać na nim mniej niż operator (operator<
).
Polecam przeczytać szablon faq: http://womble.decadentplace.org.uk/c++/template-faq.html –