The optional typename keyword in the template parameter list: is it valid or not?

The following code successfully compiles with clang 3.5.0 and g ++ 4.9.0 (with -Wall -Wextra -pedantic-errors flags) under C ++ 03 ( -std=C++03 flag) , C ++ 11 ( -std=C++11 flag -std=C++11 ) and C ++ 14 (flag -std=C++14 ) :

 namespace N { typedef int T; enum E{}; } template <typename N::T> struct ST{}; template <typename N::E> struct SE{}; int main() { } 

Is it possible to add an additional typename keyword before declaring a non-piggy type template parameter?


Please note that the following code does not compile (like C ++ 03 , C ++ 11 and C ++ 14 ):

 typedef int T; enum E{}; template <typename T t> struct ST{}; template <typename E e> struct SE{}; int main() { } 

But the following compiles again ( C ++ 03 , C ++ 11 and C ++ 14 ):

 typedef int T; enum E{}; template <typename ::T> struct ST{}; template <typename ::E> struct SE{}; int main() { } 
+5
source share
1 answer

Allowed, but only with qualified names:

TypeName specifier:
typename identifier identifier - template opt simple-template-id

So typename E is not correct according to the grammar. typename N::E is not the same as a qualified name. The third case, typename ::E , is excellent because :: is a valid nested qualifier.

The C ++ 03 standard indicates in [temp.res] / 5 that

The typename keyword should only apply to qualified names, but these names should not be dependent.

In the C ++ 11 standard, this is not explicitly stated, but inside the note in [temp.names] / 5:

[Note. As with the typename prefix, template prefix is ​​allowed in cases where it is not strictly necessary; those. when a nested name specifier or expression to the left of -> or . independent of template parameter or usage not displayed within the template. - final note]

The same note exists in the same place in the C ++ 14 standard.

+6
source

Source: https://habr.com/ru/post/1205504/


All Articles