Staffan Langin wrote:
template<class Base>
class Foo : public Base {
typedef typename Base::Type Type; //1
Type FooBar();
};
template<class Base> typename Foo<Base>::Type //2
Foo<Base>::FooBar() { return 0; }
[...]
The C++ standard requires the typename at 1 but not at 2. However, the
compiler included in Visual Studio 2005 also requires typename at 2
resulting in a LOT of errors in my current project.
I'm not confident that you're correct about (2) being allowed by the
standard without a "typename" keyword. The type Foo<Base>::Type is clearly a
dependent type on the template parameter Base, and section 14.6.3 of the ISO
C++ standard says:
"A qualified-name that refers to a type and that depends on a
template-parameter (14.6.2) shall be prefixed by the keyword typename to
indicate that the qualified-name denotes a type, forming an
elaborated-type-specifier (7.1.5.3)."
Because Foo<Base>::Type is a qualified type name (it uses ::), this seems to
mandate the keyword. Paragraphs 5 and 6 reinforce this:
"The keyword typename shall only be used in template declarations and
definitions, including [...] in the return type for the definition of a
member function of a class template [...]" (this para allows but does not
require its use here)
"Within the definition of a class template or within the definition of a
member of a class template, [...] [t]he 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."
For comparison, this (more or less) equivalent code compiles cleanly,
because it uses an unqualified type name, even though the type Type is still
dependent:
template<class Base>
class Foo : public Base {
typedef typename Base::Type Type;
Type FooBar() {
return 0;
}
};
It's possible that your previous compiler was more lenient, or
misinterpreted the standard; previous versions of Visual Studio did allow
one to omit this keyword (according to the MSDN entry for C4346). There
doesn't seem to be any ambiguity in leaving it out, since you can only have
a type name in that position, but the standard seems to require it, if I'm
not misinterpreting it. If you can justify your statement to the contrary
I'd like to hear your argument. I hope this helps.
--
Derrick Coetzee, MCP, MSFT (Speech Server)
This posting is provided "AS IS" with no warranties, and confers no
rights.