Skip to content

Use consistent terminology when referring to what a pointer to member points to #3828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -4469,7 +4469,7 @@
\item
a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator
where the left operand is one of these expressions and
the right operand is a pointer to data member of non-reference type,
the right operand is of pointer to data member type,
\item
a
\begin{itemize}
Expand Down Expand Up @@ -5196,7 +5196,7 @@
\defnx{pointers to non-static class members}{pointer to member},%
\footnote{Static class members are objects or functions, and pointers to them are
ordinary pointers to objects or functions.}
which identify members of a given
which \defn{designate} members of a given
type within objects of a given class, \ref{dcl.mptr}.
Pointers to data members and pointers to member functions are collectively
called \term{pointer-to-member} types.
Expand Down
14 changes: 6 additions & 8 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2921,8 +2921,9 @@
then the type of the identifier of
\tcode{D}
is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to member of class
\grammarterm{nested-name-specifier} of type
\tcode{T}''.
\grammarterm{nested-name-specifier} of type \tcode{T}''.
\tcode{T} is known as the \defn{member type};
it shall not be a reference type or ``\cv{}~\tcode{void}''.
The optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the
pointer-to-member.

Expand Down Expand Up @@ -2987,11 +2988,8 @@
\end{example}

\pnum
A pointer to member shall not point to a static member
of a class\iref{class.static},
a member with reference type,
or
``\cv{}~\tcode{void}''.
A pointer to member shall not designate a static member
of a class\iref{class.static}.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This restriction seems redundant; how could the "static member" situation ever arise?
&C::static_member yields a regular pointer, not a pointer to member.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True; I didn't want to drastically change it too much, be this can certainly be turned into a note saying something along the lines of: "A pointer to member designating a static member cannot be formed as there is no syntax to do so."


\pnum
\begin{note}
Expand Down Expand Up @@ -3417,7 +3415,7 @@
\begin{itemize}
\item the function type for a non-static member function,

\item the function type to which a pointer to member refers,
\item the member type\iref{dcl.mptr} of a pointer to member type,

\item the top-level function type of a function typedef declaration
or \grammarterm{alias-declaration},
Expand Down
104 changes: 46 additions & 58 deletions source/expressions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1020,9 +1020,9 @@
ambiguous\iref{class.member.lookup}, or virtual\iref{class.mi} base
class of \tcode{D}, or a base class of a virtual base class of
\tcode{D}, a program that necessitates this conversion is ill-formed.
The result of the conversion refers to the same member as the pointer to
member before the conversion took place, but it refers to the base class
member as if it were a member of the derived class. The result refers to
The result of the conversion designates the same member as the pointer to
member before the conversion took place, but it designates the base class
member as if it were a member of the derived class. The result designates
the member in \tcode{D}'s instance of \tcode{B}. Since the result has
type ``pointer to member of \tcode{D} of type \cv{} \tcode{T}'',
indirection through it with a \tcode{D} object is valid. The result is the same
Expand Down Expand Up @@ -2906,7 +2906,7 @@
implicit~(\ref{class.mfct.non-static}, \ref{class.static}) or explicit
class member access\iref{expr.ref} whose \grammarterm{id-expression} is a
function member name, or a pointer-to-member
expression\iref{expr.mptr.oper} selecting a function member; the call is as a member of
expression\iref{expr.mptr.oper} of function type; the call is as a member of
the class object referred to by the
object expression. In the case of an implicit class
member access, the implied object is the one pointed to by \tcode{this}.
Expand Down Expand Up @@ -3800,8 +3800,8 @@
The null member pointer value\iref{conv.mem} is converted to the null
member pointer value of the destination type. If class \tcode{B}
contains the original member, or is a base or derived class of the class
containing the original member, the resulting pointer to member points
to the original member. Otherwise, the behavior is undefined.
containing the original member, the resulting pointer to member designates
the original member. Otherwise, the behavior is undefined.
\begin{note}
Although class \tcode{B} need not contain the original member, the
dynamic type of the object with which indirection through the pointer
Expand Down Expand Up @@ -5582,39 +5582,35 @@
\end{bnf}

\pnum
The binary operator \tcode{.*} binds its second operand, which shall be
of type ``pointer to member of \tcode{T}'' to its first operand, which shall be
a glvalue
of
class \tcode{T} or of a class of which \tcode{T} is an unambiguous and
accessible base class. The result is an object or a function of the type
specified by the second operand.

\pnum
The binary operator \tcode{->*} binds its second operand, which shall be
of type ``pointer to member of \tcode{T}'' to its first operand, which shall be of
type ``pointer to \tcode{U}''
where \tcode{U} is either \tcode{T} or
a class of which \tcode{T}
is an unambiguous and accessible base class.
The expression \tcode{E1->*E2} is converted into the equivalent form
\tcode{(*(E1)).*E2}.
In a pointer-to-member expression of the form \tcode{E1->*E2}, \tcode{E2} shall
be of type ``pointer to member of \tcode{T}'' and \tcode{E1} shall be of type
``pointer to \cv{}~\tcode{U}'' where \tcode{U} is \tcode{T} or a type of which
\tcode{T} is an accessible and unambiguous base class. The expression is converted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be redundant with the checks after the rewrite.

Copy link
Contributor Author

@sdkrystian sdkrystian Apr 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My intent was to allow for the reader to clearly reason the requirements on the operands, but this could be replaced with:

In a pointer-to-member expression of the form E1->*E2, E1 shall be a prvalue of pointer to object type. The expression is converted to the equivalent form (*(E1)).*E2; the remainder of this subclause will
address only the operator .*.

to the equivalent form \tcode{(*(E1)).*E2}; the remainder of this subclause will
address only the operator \tcode{.*}.

\pnum
Abbreviating \grammarterm{pm-expression}\tcode{.*}\grammarterm{cast-expression} as \tcode{E1.*E2},
\tcode{E2} shall be of type ``pointer to member of \tcode{T}'', and \tcode{E1} shall be a glvalue
of type \tcode{T} or a type of which \tcode{T} is an accessible and unambiguous base class
(ignoring cv-qualification). The expression \tcode{E1} is known as the \defn{object expression}.
If \tcode{E2} is the null-member-pointer value, or the member \tcode{E2} designates is not a
member of the the dynamic type of the object expression, the behavior is undefined.
The result is the member subobject or function designated
by \tcode{E2} corresponding to the object denoted by the object expression;
the expression is a prvalue if the result is a function, and otherwise has
the same value category as the (possibly-converted) object expression.
The expression \tcode{E1} is sequenced before the expression \tcode{E2}.

\pnum
Abbreviating \grammarterm{pm-expression}\tcode{.*}\grammarterm{cast-expression} as \tcode{E1.*E2}, \tcode{E1}
is called the \defn{object expression}.
If the dynamic type of \tcode{E1} does not
contain the member to which
\tcode{E2} refers, the behavior is undefined.
Otherwise, the expression \tcode{E1} is sequenced before the expression \tcode{E2}.
The manner in which the cv-qualifiers of the operands are combined
to produce the cv-qualifiers of the result are the same as those
specified in~\ref{expr.ref} for the expression \tcode{E1.M}, where
the invented \grammarterm{id-expression} \tcode{M} denotes the same
member \tcode{E2} designates.

\pnum
The restrictions on cv-qualification, and the manner in which
the cv-qualifiers of the operands are combined to produce the
cv-qualifiers of the result, are the same as the rules for
\tcode{E1.E2} given in~\ref{expr.ref}.
\begin{note}
It is not possible to use a pointer to member that refers to a
It is not possible to use a pointer to member designating a
\tcode{mutable} member to modify a const class object. For
example,
\begin{codeblock}
Expand All @@ -5625,39 +5621,31 @@
void f()
{
const S cs;
int S::* pm = &S::i; // \tcode{pm} refers to \tcode{mutable} member \tcode{S::i}
int S::* pm = &S::i; // \tcode{pm} designates the \tcode{mutable} member \tcode{S::i}
cs.*pm = 88; // error: \tcode{cs} is a const object
}
\end{codeblock}
\end{note}

\pnum
\indextext{function!pointer to member}%
If the result of \tcode{.*} or \tcode{->*} is a function, then that
result can be used only as the operand for the function call operator
\tcode{()}.
If the result of a pointer-to-member expression is a function, the
result can be used only as the left-hand operand of a member function call.
\begin{example}
\begin{codeblock}
(ptr_to_obj->*ptr_to_mfct)(10);
\end{codeblock}
calls the member function denoted by \tcode{ptr_to_mfct} for the object
calls the member function designated by \tcode{ptr_to_mfct} for the object
pointed to by \tcode{ptr_to_obj}.
\end{example}
In a \tcode{.*} expression whose object expression is an rvalue, the program is
ill-formed if the second operand is a pointer to member function
whose \grammarterm{ref-qualifier} is \tcode{\&},
unless its \grammarterm{cv-qualifier-seq} is \tcode{const}.
In a \tcode{.*}
expression whose object expression is an lvalue, the program is ill-formed if the second
operand is
a pointer to member function
whose \grammarterm{ref-qualifier} is \tcode{\&\&}.
The result of a \tcode{.*} expression
whose second operand is a pointer to a data member is an lvalue if the first
operand is an lvalue and an xvalue otherwise. The result of a \tcode{.*} expression whose
second operand is a pointer to a member function is a prvalue.
If the second operand is the null
member pointer value\iref{conv.mem}, the behavior is undefined.

\pnum
In a pointer-to-member expression whose object expression is an xvalue,
if the second operand is of pointer-to-member-function type, the member type\iref{dcl.mptr}
shall not have the \grammarterm{ref-qualifier} \tcode{\&} unless its \grammarterm{cv-qualifier-seq}
is \tcode{const}. Similarly, in a pointer-to-member expression whose object expression is an lvalue,
if the second operand is of pointer-to-member-function type, the member type\iref{dcl.mptr}
shall not have the \grammarterm{ref-qualifier} \tcode{\&\&}.

\rSec2[expr.mul]{Multiplicative operators}%
\indextext{expression!multiplicative operators}%
Expand Down Expand Up @@ -6155,7 +6143,7 @@
If either is a pointer to a virtual member function, the result is unspecified.

\item
If one refers to a member of class \tcode{C1} and the other refers to a member
If one designates a member of class \tcode{C1} and the other designates a member
of a different class \tcode{C2}, where neither is a base class of the other,
the result is unspecified.
\begin{example}
Expand All @@ -6172,11 +6160,11 @@
\end{example}

\item
If both refer to (possibly different) members of the same union\iref{class.union},
If both designate (possibly different) members of the same union\iref{class.union},
they compare equal.

\item
Otherwise, two pointers to members compare equal if they would refer to the same member of
Otherwise, two pointers to members compare equal if they would designate the same member of
the same most derived object\iref{intro.object} or the same subobject if
indirection with a hypothetical object of the associated
class type were performed, otherwise they compare unequal.
Expand Down
4 changes: 2 additions & 2 deletions source/templates.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2084,7 +2084,7 @@
they are of pointer type and they have the same pointer value, or

\item
they are of pointer-to-member type and they refer to the same class member
they are of pointer-to-member type and they designate the same class member
or are both the null member pointer value, or

\item
Expand Down Expand Up @@ -8531,7 +8531,7 @@
and the return type.
\item
A pointer-to-member type includes the type of the class object pointed to
and the type of the member pointed to.
and the member type\iref{dcl.mptr}.
\item
A type that is a specialization of a class template (e.g.,
\tcode{A<int>})
Expand Down