I was reading this article from this page, so let me present the code:
template <class T> class D: typename C<T>::Base { //#1 error
D(): typename C<T>::Base(typename C<T>::Base(0)) { } //#2 error, #3 correct
typename C<T> f() { //#4 error
typename C<T>::A* p; //#5 correct
A<T>::B * n;
}
};
class Q{
typename C<long>::A * p; // #6 error
}
template <class T, class U> class R{
typename C<long>::A * p; // #7 optional
}
#3
is correct but I am trying to understand what the author is attempting to convey. He says:
typename #3: correct. Here, typename is used for disambiguating the type of a parameter. Without typename, the expression C::Base(0) would be treated as a call to a function called Base. With the typename prefix, C::Base(0) creates a temporary object of type C::Base initialized with the argument 0.
Also, if you see a little above that part the author says:
The typename keyword must prefix a dependent name when that name satisfies the following three rules:
1.It appears inside a template
2.It's qualified // i开发者_如何学编程 am unable to understand this line at all in conjunction with starting para of this quote
3.It isn’t used in a base class specification or a member initialization list.
I am unable to understand this line (#2 above) at all in conjunction with starting paragraph of this quote. Can you explain what the author means?
"Qualified" means that it is not in the same scope, but a subscope of the current one, which also depends on a template. For instance,
template <class T> struct C {
typedef int b;
}
b
is a qualified id
when referenced in another template e.g
template<typename T> struct M {
typename C<T>::b bb;
}
Relevant quote from the standard (§14.6.3):
A qualified-id that refers to a type and in which the nested-name-specifier depends on a template-parameter (14.6.2) shall be prefixed by the keyword typename to indicate that the qualified-id denotes a type, forming an elaborated-type-specifier (7.1.5.3).
And §14.6.2:
A name used in a template declaration or definition and that is dependent on a template-parameter is
assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified
by the keyword typename. [Example:
// no B declared here
class X;
template<class T> class Y {
class Z; // forward declaration of member class
void f() {
X* a1; // declare pointer to X
T* a2; // declare pointer to T
Y* a3; // declare pointer to Y<T>
Z* a4; // declare pointer to Z
typedef typename T::A TA;
TA* a5; // declare pointer to T’s A
typename T::A* a6; // declare pointer to T’s A
T::A* a7; // T::A is not a type name:
// multiply T::A by a7; ill-formed,
// no visible declaration of a7
B* a8; // B is not a type name:
// multiply B by a8; ill-formed,
// no visible declarations of B and a8
}
};
—end example]
And §14.6.7:
Within the definition of a class template or within the definition of a member of a class template, the keyword
typename is not required when referring to the unqualified name of a previously declared member
of the class template that declares a type. The keyword typename shall always be specified when the
member is referred to using a qualified name, even if the qualifier is simply the class template name.
[Example:
template<class T> struct A {
typedef int B;
A::B b; // ill-formed: typename required before A::B
void f(A<T>::B); // ill-formed: typename required before A<T>::B
typename A::B g(); // OK
};
The keyword typename is required whether the qualified name is A or A<T> because A or A<T> are synonyms
within a class template with the parameter list <T>. ]
Not sure if this might help, but an example of template usage:
template<typename TemplateVar>
class SimpleTemplate
{
public:
TemplateVar Item;
void SetItem(TemplateVar &ItemCopy);
TemplateVar &GetItem();
};
template<typename TemplateVar>
void SimpleTemplate<TemplateVar>::SetItem(TemplateVar &ItemCopy)
{
Item = ItemCopy;
return;
}
template<typename TemplateVar>
TemplateVar &SimpleTemplate<TemplateVar>::GetItem()
{
return Item;
}
int main(int ArgC, char *ArgV[])
{
SimpleTemplate<char> Test;
return 0;
}
Feel free to do whatever you want with the code (even sell it, if you can).
精彩评论