Skip to content

Commit 7297bb9

Browse files
committed
P0634R3 Down with typename!
1 parent ac5706f commit 7297bb9

File tree

1 file changed

+75
-43
lines changed

1 file changed

+75
-43
lines changed

source/templates.tex

Lines changed: 75 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4015,35 +4015,17 @@
40154015
\end{codeblock}
40164016
\end{example}
40174017

4018-
\pnum
4019-
When a \grammarterm{qualified-id} is intended to refer to a type
4020-
that is not a member of the current instantiation\iref{temp.dep.type}
4021-
and its \grammarterm{nested-name-specifier}
4022-
refers to a dependent type,
4023-
it shall be
4024-
prefixed by the keyword \tcode{typename}, forming a
4025-
\grammarterm{typename-specifier}.
4026-
If the \grammarterm{qualified-id} in a \grammarterm{typename-specifier}
4027-
does not denote a type
4028-
or a class template,
4029-
the program is ill-formed.
4030-
40314018
\begin{bnf}
40324019
\nontermdef{typename-specifier}\br
40334020
\terminal{typename} nested-name-specifier identifier\br
40344021
\terminal{typename} nested-name-specifier \terminal{\opt{template}} simple-template-id
40354022
\end{bnf}
40364023

40374024
\pnum
4038-
If a specialization of a template is instantiated for a set of
4039-
\grammarterm{template-argument}{s}
4040-
such that the
4041-
\grammarterm{qualified-id}
4042-
prefixed by
4043-
\tcode{typename}
4044-
does not denote a type
4045-
or a class template,
4046-
the specialization is ill-formed.
4025+
A \grammarterm{typename-specifier}
4026+
denotes the type or class template
4027+
denoted by the \grammarterm{simple-type-specifier}\iref{dcl.type.simple}
4028+
formed by omitting the keyword \tcode{typename}.
40474029
The usual qualified name lookup\iref{basic.lookup.qual} is used to find the
40484030
\grammarterm{qualified-id}
40494031
even in the presence of
@@ -4088,20 +4070,75 @@
40884070
\end{note}
40894071

40904072
\pnum
4091-
If, for a given set of template arguments, a specialization of a template is
4092-
instantiated
4093-
that refers to a \grammarterm{qualified-id}
4094-
that denotes a type
4095-
or a class template,
4096-
and the
4097-
\grammarterm{qualified-id} refers to a member of an unknown specialization,
4098-
the \grammarterm{qualified-id} shall either be
4099-
prefixed by \tcode{typename} or shall be used in a context in which it
4100-
implicitly names a type as described above. \begin{example}
4073+
A \grammarterm{qualified-id}
4074+
is assumed to name a type if
4075+
\begin{itemize}
4076+
\item it is a qualified name in a type-id-only context (see below), or
4077+
\item it is a \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} of a
4078+
\begin{itemize}
4079+
\item \grammarterm{simple-declaration} or a \grammarterm{function-definition} in namespace scope,
4080+
\item \grammarterm{member-declaration},
4081+
\item \grammarterm{parameter-declaration} in a \grammarterm{member-declaration},
4082+
unless that \grammarterm{parameter-declaration} appears in a default argument
4083+
\begin{note} This includes friend function declarations. \end{note},
4084+
\item \grammarterm{parameter-declaration} in a \grammarterm{declarator}
4085+
of a function or function template declaration
4086+
where the \grammarterm{declarator-id} is qualified,
4087+
unless that \grammarterm{parameter-declaration}
4088+
appears in a default argument,
4089+
\item \grammarterm{parameter-declaration} in a \grammarterm{lambda-declarator},
4090+
unless that \grammarterm{parameter-declaration} appears in a default argument, or
4091+
\item \grammarterm{parameter-declaration} of a (non-type) \grammarterm{template-parameter}.
4092+
\end{itemize}
4093+
\end{itemize}
4094+
A qualified name is said to be in a \defn{type-id-only context}
4095+
if it appears in a
4096+
\grammarterm{type-id},
4097+
\grammarterm{new-type-id}, or
4098+
\grammarterm{defining-type-id}
4099+
and the smallest enclosing
4100+
\grammarterm{type-id},
4101+
\grammarterm{new-type-id}, or
4102+
\grammarterm{defining-type-id}
4103+
is a
4104+
\grammarterm{new-type-id},
4105+
\grammarterm{defining-type-id},
4106+
\grammarterm{trailing-return-type},
4107+
default argument of a \grammarterm{type-parameter} of a template, or
4108+
\grammarterm{type-id} of a
4109+
\tcode{static_cast},
4110+
\tcode{const_cast},
4111+
\tcode{reinterpret_cast}, or
4112+
\tcode{dynamic_cast}.
4113+
\begin{example}
4114+
\begin{codeblock}
4115+
template<class T> T::R f(); // OK, return type of a function declaration at global scope
4116+
template<class T> void f(T::R); // ill-formed (no diagnostic required), attempt to declare a \tcode{void} variable template
4117+
template<class T> struct S {
4118+
using Ptr = PtrTraits<T>::Ptr; // OK, in a \grammarterm{defining-type-id}
4119+
T::R f(T::P p) { // OK, class scope
4120+
return static_cast<T::R>(p); // OK, \grammarterm{type-id} of a \tcode{static_cast}
4121+
}
4122+
auto g() -> S<T*>::Ptr;  // OK, \grammarterm{trailing-return-type}
4123+
};
4124+
template<typename T> void f() {
4125+
void (*pf)(T::X); // variable \tcode{pf} of type \tcode{void*} initialized with \tcode{T::X}
4126+
void g(T::X); // error: \tcode{T::X} at block scope does not denote a type
4127+
// (attempt to declare a \tcode{void} variable)
4128+
}
4129+
\end{codeblock}
4130+
\end{example}
4131+
4132+
\pnum
4133+
A \grammarterm{qualified-id} that refers to a member of an unknown specialization,
4134+
that is not prefixed by \tcode{typename},
4135+
and that is not otherwise assumed to name a type (see above)
4136+
denotes a non-type.
4137+
\begin{example}
41014138

41024139
\begin{codeblock}
41034140
template <class T> void f(int i) {
4104-
T::x * i; // \tcode{T::x} must not be a type
4141+
T::x * i; // expression, not the declaration of a variable \tcode{i}
41054142
}
41064143

41074144
struct Foo {
@@ -4123,29 +4160,24 @@
41234160
Within the definition of a class template or within the definition of a
41244161
member of a class template following the \grammarterm{declarator-id}, the keyword
41254162
\tcode{typename}
4126-
is not required when referring to the name of a previously
4127-
declared member of the class template that declares a type
4128-
or a class template.
4129-
\begin{note} Such names can be found using unqualified name lookup\iref{basic.lookup.unqual},
4130-
class member lookup\iref{class.qual} into the current instantiation\iref{temp.dep.type},
4131-
or class member access expression lookup\iref{basic.lookup.classref} when the
4132-
type of the object expression is the current instantiation\iref{temp.dep.expr}.
4133-
\end{note}
4163+
is not required when referring to
4164+
a member of the current instantiation\iref{temp.dep.type}.
41344165
\begin{example}
4135-
41364166
\begin{codeblock}
41374167
template<class T> struct A {
41384168
typedef int B;
4139-
B b; // OK, no typename required
4169+
B b; // OK, no \tcode{typename} required
41404170
};
41414171
\end{codeblock}
41424172
\end{example}
41434173

41444174
\pnum
41454175
\indextext{checking!syntax}%
41464176
\indextext{checking!point of error}%
4177+
\begin{note}
41474178
Knowing which names are type names allows the syntax of every template
41484179
to be checked.
4180+
\end{note}
41494181
The program is ill-formed, no diagnostic required, if:
41504182

41514183
\begin{itemize}

0 commit comments

Comments
 (0)