Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
31 Views

typename outside of template

I have been burn a couple of times by trying to check in the following:
template
struct S{
typedef S SType;
};
int main(void )
{
typedef S MyType;
typename MyType::SType s;
return 0;
}

template struct S{typedef S SType;};
int main(void ){
typedef S MyType;
typename MyType::SType s;
return 0;
}
icpc compiles this with out complaints. But gcc and many other compilers give and error similar too:
error: using typename outside of template
I tried adding the -std=gnu++98 in hopes that the C++0x relaxed this rule, but it still compiled without error or warning.
Ideally I'd like this code to generate an error, I would be satisfied with just a warning though... any ideas?
Thanks,
Brad
0 Kudos
4 Replies
Highlighted
Moderator
31 Views

try "-w5"
I got the warnings on Windows with "-W5".

Jennifer
0 Kudos
Highlighted
Employee
31 Views

In the old C++98 standard, the code was invalid because the typename keyword can only be used in qualified type that depends on a template parameter.

In thecode there is no dependent template so use of the word typename is illegal.

But this has changed in c++0x. These are the notes from the Core Issues List:

382. Allow typename outside of templates

(#66) Section: 14.6 temp.res Status: drafting Submitter: Steve Adamczyk Date: 8 Nov 2002 Priority: 1 Drafting: Nelson

P. J. Plauger, among others, has noted that typename is hard to use, because in a given context it's either required or forbidden, and it's often hard to tell which. It would make life easier for programmers if typename could be allowed in places where it is not required, e.g., outside of templates.

Notes from the April 2003 meeting:

There was unanimity on relaxing this requirement on typename. The question was how much to relax it. Everyone agreed on allowing it on all qualified names, which is an easy fix (no syntax change required). But should it be allowed other places? P.J. Plauger said he'd like to see it allowed anywhere a type name is allowed, and that it could actually be a decades-late assist for the infamous "the ice is thin here" typedef problem noted in K&R I.

Proposed resolution (April 2003):

Replace the text at the start of 14.6 temp.res paragraph 3:

A qualified-id that refers to a type and in which the nested-name-specifier depends on a template-parameter (14.6.2 temp.dep) 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 dcl.type.elab).

With:

The keyword typename can only be applied to a qualified-id. A qualified-id that refers to a type and in which the nested-name-specifier depends on a template-parameter (14.6.2 temp.dep) 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 dcl.type.elab). If a qualified-id which has been prefixed by the keyword typename does not denote a type the program is ill-formed. [ Note: The keyword is only required on a qualified-id within a template declaration or definition in which the nested-name-specifier depends on a template-parameter. ]

Remove 14.6 temp.res paragraph 5:

The keyword typename shall only be used in template declarations and definitions, including in the return type of a function template or member function template, in the return type for the definition of a member function of a class template or of a class nested within a class template, and in the type-specifier for the definition of a static member of a class template or of a class nested within a class template. The keyword typename shall be applied only to qualified names, but those names need not be dependent. The keyword typename shall be used only in contexts in which dependent names can be used. This includes template declarations and definitions but excludes explicit specialization declarations and explicit instantiation declarations. The keyword typename is not permitted in a base-specifier or in a mem-initializer; in these contexts a qualified-id that depends on a template-parameter (temp.dep) is implicitly assumed to be a type name.

Note: the claim here that a qualified name preceded by typename forms an elaborated type specifier conflicts with the changes made in issue 254 (see N1376=02-0034), which introduces typename-specifier.

Notes from October 2003 meeting:

We considered whether typename should be allowed in more places, and decided we only wanted to allow it in qualified names (for now at least).

Core issue 254 changed elaborated-type-specifier to typename-specifier. It also changed 14.6 temp.res paragraph 5, which this proposed resolution deletes. Back to Nelson for redrafting.

0 Kudos
Highlighted
31 Views

Thank you for the wealth of detailed information. I think I am understanding the notes.
So should the "-std=gnu++98" compile the above code or produce an error?
The documentation for this option says: "Conforms to the 1998 ISO C++ standard plus GNU extensions."While the default "-std=c++0x" includes in its features "Relaxed rules for use of 'typename'".However, it seams like the typename usage is already relaxed with the implicit -std=gnu++98 option.Hence my confusion on if the validility of the above code should change, as it does not conform to C++98 nor to my knowledge is an gnu extension.
0 Kudos
Highlighted
Employee
31 Views


In default mode, the Gnu and Intel compilers willsometimes accept code that doesn't conform to the standard as long as it won't lead to potential runtime problems. If you use the Intel Linux -strict_ansi option you will get a warning:

sptxl8-37> icpc -strict_ansi -c ex.cpp
ex.cpp(9): warning #804: typename may only be used within a template
typename MyType::SType s;
^
0 Kudos