Skip to content

Commit 69392bf

Browse files
authored
Merge 2021-10 CWG Motion 3
P0847R7 Deducing this
2 parents dcb4f8f + 76fc1ce commit 69392bf

7 files changed

+238
-55
lines changed

source/basic.tex

+43-12
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,32 @@
865865
\end{itemize}
866866
\end{note}
867867

868+
\pnum
869+
Two non-static member functions have
870+
\defnadjx{corresponding}{object parameters}{object parameter} if:
871+
\begin{itemize}
872+
\item
873+
exactly one is an implicit object member function
874+
with no \grammarterm{ref-qualifier} and
875+
the types of their object parameters\iref{dcl.fct},
876+
after removing top-level references,
877+
are the same, or
878+
\item
879+
their object parameters have the same type.
880+
\end{itemize}
881+
Two non-static member function templates have
882+
\defnadjx{corresponding}{object parameters}{object parameter} if:
883+
\begin{itemize}
884+
\item
885+
exactly one is an implicit object member function
886+
with no \grammarterm{ref-qualifier} and
887+
the types of their object parameters,
888+
after removing any references,
889+
are equivalent, or
890+
\item
891+
the types of their object parameters are equivalent.
892+
\end{itemize}
893+
868894
\pnum
869895
Two declarations \defn{correspond}
870896
if they (re)introduce the same name,
@@ -885,25 +911,23 @@
885911
each declares a function or function template, except when
886912
\begin{itemize}
887913
\item
888-
both declare functions with the same parameter-type-list,
914+
both declare functions with the same non-object-parameter-type-list,
889915
\begin{footnote}
890916
An implicit object parameter\iref{over.match.funcs}
891917
is not part of the parameter-type-list.
892918
\end{footnote}
893919
equivalent\iref{temp.over.link} trailing \grammarterm{requires-clause}s
894920
(if any, except as specified in \ref{temp.friend}), and,
895921
if both are non-static members,
896-
the same \grammarterm{cv-qualifier}s (if any) and
897-
\grammarterm{ref-qualifier} (if both have one), or
922+
they have corresponding object parameters, or
898923
\item
899924
both declare function templates with equivalent
900-
parameter-type-lists,
925+
non-object-parameter-type-lists,
901926
return types (if any),
902927
\grammarterm{template-head}s, and
903928
trailing \grammarterm{requires-clause}s (if any), and,
904929
if both are non-static members,
905-
the same \grammarterm{cv-qualifier}s (if any) and
906-
\grammarterm{ref-qualifier} (if both have one).
930+
they have corresponding object parameters.
907931
\end{itemize}
908932
\end{itemize}
909933
\begin{note}
@@ -923,16 +947,23 @@
923947
\begin{codeblock}
924948
typedef int Int;
925949
enum E : int { a };
926-
void f(int); // \#1
927-
void f(Int) {} // defines \#1
928-
void f(E) {} // OK: another overload
950+
void f(int); // \#1
951+
void f(Int) {} // defines \#1
952+
void f(E) {} // OK: another overload
929953

930954
struct X {
931955
static void f();
932-
void f() const; // error: redeclaration
956+
void f() const; // error: redeclaration
933957
void g();
934-
void g() const; // OK
935-
void g() &; // error: redeclaration
958+
void g() const; // OK
959+
void g() &; // error: redeclaration
960+
961+
void h(this X&, int);
962+
void h(int) &&; // OK: another overload
963+
void j(this const X&);
964+
void j() const&; // error: redeclaration
965+
void k();
966+
void k(this X&); // error: redeclaration
936967
};
937968
\end{codeblock}
938969
\end{example}

source/classes.tex

+3-3
Original file line numberDiff line numberDiff line change
@@ -997,15 +997,15 @@
997997
\indextext{member function!volatile}%
998998
\indextext{member function!const volatile}%
999999
\begin{note}
1000-
A non-static member function can be declared with
1000+
An implicit object member function can be declared with
10011001
\grammarterm{cv-qualifier}{s}, which affect the type of the \keyword{this}
10021002
pointer\iref{expr.prim.this},
10031003
and/or a \grammarterm{ref-qualifier}\iref{dcl.fct};
10041004
both affect overload resolution\iref{over.match.funcs}
10051005
\end{note}
10061006

10071007
\pnum
1008-
A non-static member function may be declared
1008+
An implicit object member function may be declared
10091009
virtual\iref{class.virtual} or pure virtual\iref{class.abstract}.
10101010

10111011
\rSec2[special]{Special member functions}
@@ -2487,7 +2487,7 @@
24872487
\nontermdef{conversion-declarator}\br
24882488
ptr-operator \opt{conversion-declarator}
24892489
\end{bnf}
2490-
shall have no parameters and
2490+
shall have no non-object parameters and
24912491
specifies a conversion from \tcode{X} to
24922492
the type specified by the \grammarterm{conversion-type-id},
24932493
interpreted as a \grammarterm{type-id}\iref{dcl.name}.

source/declarations.tex

+69-9
Original file line numberDiff line numberDiff line change
@@ -3435,10 +3435,10 @@
34353435

34363436
\begin{bnf}
34373437
\nontermdef{parameter-declaration}\br
3438-
\opt{attribute-specifier-seq} decl-specifier-seq declarator\br
3439-
\opt{attribute-specifier-seq} decl-specifier-seq declarator \terminal{=} initializer-clause\br
3440-
\opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator}\br
3441-
\opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause
3438+
\opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq declarator\br
3439+
\opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq declarator \terminal{=} initializer-clause\br
3440+
\opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq \opt{abstract-declarator}\br
3441+
\opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause
34423442
\end{bnf}
34433443

34443444
The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration}
@@ -3547,6 +3547,66 @@
35473547
\end{codeblock}
35483548
\end{example}
35493549

3550+
\pnum
3551+
An \defn{explicit-object-parameter-declaration} is
3552+
a \grammarterm{parameter-declaration} with a \keyword{this} specifier.
3553+
An explicit-object-parameter-declaration shall appear only as
3554+
the first \grammarterm{parameter-declaration} of
3555+
a \grammarterm{parameter-declaration-list} of either:
3556+
\begin{itemize}
3557+
\item
3558+
a \grammarterm{member-declarator}
3559+
that declares a member function\iref{class.mem}, or
3560+
\item
3561+
a \grammarterm{lambda-declarator}\iref{expr.prim.lambda}.
3562+
\end{itemize}
3563+
A \grammarterm{member-declarator} with an explicit-object-parameter-declaration
3564+
shall not include
3565+
a \grammarterm{ref-qualifier} or a \grammarterm{cv-qualifier-seq} and
3566+
shall not be declared \keyword{static} or \keyword{virtual}.
3567+
\begin{example}
3568+
\begin{codeblock}
3569+
struct C {
3570+
void f(this C& self);
3571+
template <typename Self> void g(this Self&& self, int);
3572+
3573+
void h(this C) const; // error: \tcode{const} not allowed here
3574+
};
3575+
3576+
void test(C c) {
3577+
c.f(); // OK, calls \tcode{C::f}
3578+
c.g(42); // OK, calls \tcode{C::g<C\&>}
3579+
std::move(c).g(42); // OK, calls \tcode{C::g<C>}
3580+
}
3581+
\end{codeblock}
3582+
\end{example}
3583+
3584+
\pnum
3585+
A function parameter declared with an explicit-object-parameter-declaration
3586+
is an \defnadj{explicit object}{parameter}.
3587+
An explicit object parameter shall not be
3588+
a function parameter pack\iref{temp.variadic}.
3589+
An \defnadj{explicit object}{member function} is a non-static member function
3590+
with an explicit object parameter.
3591+
An \defnadj{implicit object}{member function} is a non-static member function
3592+
without an explicit object parameter.
3593+
3594+
\pnum
3595+
The \defnadj{object}{parameter} of a non-static member function is either
3596+
the explicit object parameter or
3597+
the implicit object parameter\iref{over.match.funcs}.
3598+
3599+
\pnum
3600+
A \defnadj{non-object}{parameter} is a function parameter
3601+
that is not the explicit object parameter.
3602+
The \defn{non-object-parameter-type-list} of a member function is
3603+
the parameter-type-list of that function with the explicit object parameter,
3604+
if any, omitted.
3605+
\begin{note}
3606+
The non-object-parameter-type-list consists of
3607+
the adjusted types of all the non-object parameters.
3608+
\end{note}
3609+
35503610
\pnum
35513611
A function type with a \grammarterm{cv-qualifier-seq} or a
35523612
\grammarterm{ref-qualifier} (including a type named by
@@ -6378,19 +6438,19 @@
63786438
\tcode{std::coroutine_traits<R, P$_1$, $\dotsc$, P$_n$>::promise_type},
63796439
where
63806440
\tcode{R} is the return type of the function, and
6381-
$\tcode{P}_1 \dotsc \tcode{P}_n$ are the sequence of types of the function parameters,
6382-
preceded by the type of the implicit object parameter\iref{over.match.funcs}
6441+
$\tcode{P}_1 \dotsc \tcode{P}_n$ are the sequence of types of the non-object function parameters,
6442+
preceded by the type of the object parameter\iref{dcl.fct}
63836443
if the coroutine is a non-static member function.
63846444
The promise type shall be a class type.
63856445

63866446
\pnum
63876447
In the following, $\tcode{p}_i$ is an lvalue of type $\tcode{P}_i$,
63886448
where
6389-
$\tcode{p}_1$ denotes \tcode{*this} and
6390-
$\tcode{p}_{i+1}$ denotes the $i^\textrm{th}$ function parameter
6449+
$\tcode{p}_1$ denotes the object parameter and
6450+
$\tcode{p}_{i+1}$ denotes the $i^\text{th}$ non-object function parameter
63916451
for a non-static member function, and
63926452
$\tcode{p}_i$ denotes
6393-
the $i^\textrm{th}$ function parameter otherwise.
6453+
the $i^\text{th}$ function parameter otherwise.
63946454
For a non-static member function,
63956455
$\tcode{q}_1$ is an lvalue that denotes \tcode{*this};
63966456
any other $\tcode{q}_i$ is an lvalue

source/expressions.tex

+56-7
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@
11941194

11951195
\pnum
11961196
\indextext{\idxcode{this}}%
1197-
The keyword \keyword{this} names a pointer to the object for which a non-static member
1197+
The keyword \keyword{this} names a pointer to the object for which an implicit object member
11981198
function\iref{class.mfct.non-static} is invoked or a non-static data member's
11991199
initializer\iref{class.mem} is evaluated.
12001200

@@ -1213,8 +1213,10 @@
12131213
between the optional
12141214
\grammarterm{cv-qualifier-seq} and the end of the \grammarterm{function-definition},
12151215
\grammarterm{member-declarator}, or \grammarterm{declarator}. It shall not appear within
1216-
the declaration of a static member function of the current class (although its type and value category
1217-
are defined within a static member function as they are within a non-static
1216+
the declaration of either
1217+
a static member function or an explicit object member function
1218+
of the current class (although its type and value category
1219+
are defined within such member functions as they are within an implicit object
12181220
member function).
12191221
\begin{note}
12201222
This is because declaration matching does not
@@ -1450,7 +1452,7 @@
14501452
the type of a class member access expression\iref{expr.ref}
14511453
naming the non-static data member
14521454
that would be declared for such a capture
1453-
in the closure object of
1455+
in the object parameter\iref{dcl.fct} of the function call operator of
14541456
the innermost such intervening \grammarterm{lambda-expression}.
14551457
\begin{note}
14561458
If that \grammarterm{lambda-expression} is not declared \keyword{mutable},
@@ -1688,6 +1690,10 @@
16881690
In the \grammarterm{decl-specifier-seq} of the \grammarterm{lambda-declarator},
16891691
each \grammarterm{decl-specifier}
16901692
shall be one of \keyword{mutable}, \keyword{constexpr}, or \keyword{consteval}.
1693+
If the \grammarterm{lambda-declarator} contains
1694+
an explicit object parameter\iref{dcl.fct},
1695+
then no \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq}
1696+
shall be \keyword{mutable}.
16911697
\begin{note}
16921698
The trailing \grammarterm{requires-clause} is described in \ref{dcl.decl}.
16931699
\end{note}
@@ -1792,14 +1798,51 @@
17921798
{ std::cout << v1 << v2 << v3; } );
17931799
auto q = p(1, 'a', 3.14); // OK: outputs \tcode{1a3.14}
17941800
q(); // OK: outputs \tcode{1a3.14}
1801+
1802+
auto fact = [](this auto self, int n) -> int { // OK: explicit object parameter
1803+
return (n <= 1) ? 1 : n * self(n-1);
1804+
};
1805+
std::cout << fact(5); // OK: outputs 120
1806+
\end{codeblock}
1807+
\end{example}
1808+
1809+
\pnum
1810+
Given a lambda with a \grammarterm{lambda-capture},
1811+
the type of the explicit object parameter, if any,
1812+
of the lambda's function call operator
1813+
(possibly instantiated from a function call operator template)
1814+
shall be either:
1815+
\begin{itemize}
1816+
\item
1817+
the closure type,
1818+
\item
1819+
a class type derived from the closure type, or
1820+
\item
1821+
a reference to a possibly cv-qualified such type.
1822+
\end{itemize}
1823+
\begin{example}
1824+
\begin{codeblock}
1825+
struct C {
1826+
template <typename T>
1827+
C(T);
1828+
};
1829+
1830+
void func(int i) {
1831+
int x = [=](this auto&&) { return i; }(); // OK
1832+
int y = [=](this C) { return i; }(); // error
1833+
int z = [](this C) { return 42; }(); // OK
1834+
}
17951835
\end{codeblock}
17961836
\end{example}
17971837

17981838
\pnum
17991839
The function call operator or operator template is declared
18001840
\keyword{const}~(\ref{class.mfct.non-static}) if and only if the
18011841
\grammarterm{lambda-expression}'s \grammarterm{parameter-declaration-clause} is not
1802-
followed by \keyword{mutable}. It is neither virtual nor declared \tcode{volatile}. Any
1842+
followed by \keyword{mutable} and
1843+
the \grammarterm{lambda-declarator} does not contain
1844+
an explicit object parameter.
1845+
It is neither virtual nor declared \tcode{volatile}. Any
18031846
\grammarterm{noexcept-specifier} specified on a \grammarterm{lambda-expression}
18041847
applies to the corresponding function call operator or operator template.
18051848
An \grammarterm{attribute-specifier-seq} in a \grammarterm{lambda-declarator} appertains
@@ -3082,6 +3125,10 @@
30823125
When a function is called, each parameter\iref{dcl.fct} is
30833126
initialized~(\ref{dcl.init}, \ref{class.copy.ctor}) with
30843127
its corresponding argument.
3128+
If the function is an explicit object member function and
3129+
there is an implied object argument\iref{over.call.func},
3130+
the list of provided arguments is preceded by the implied object argument
3131+
for the purposes of this correspondence.
30853132
If there is no corresponding argument,
30863133
the default argument for the parameter is used.
30873134
\begin{example}
@@ -3090,7 +3137,7 @@
30903137
int x = f<int>(); // error: no argument for second function parameter
30913138
\end{codeblock}
30923139
\end{example}
3093-
If the function is a non-static member
3140+
If the function is an implicit object member
30943141
function, the \keyword{this} parameter of the function\iref{expr.prim.this}
30953142
is initialized with a pointer to the object of the call, converted
30963143
as if by an explicit type conversion\iref{expr.cast}.
@@ -4337,11 +4384,13 @@
43374384
\begin{itemize}
43384385
\item
43394386
If the operand is a \grammarterm{qualified-id} naming a non-static or variant member \tcode{m}
4340-
of some class \tcode{C}, the result has type ``pointer to member
4387+
of some class \tcode{C}, other than an explicit object member function, the result has type ``pointer to member
43414388
of class \tcode{C} of type \tcode{T}'' and designates \tcode{C::m}.
43424389
\item
43434390
Otherwise, the result has type ``pointer to \tcode{T}'' and points to
43444391
the designated object\iref{intro.memory} or function\iref{basic.compound}.
4392+
If the operand names an explicit object member function\iref{dcl.fct},
4393+
the operand shall be a \grammarterm{qualified-id}.
43454394
\begin{note}
43464395
In particular, taking the address of a variable of type ``\cv{}~\tcode{T}''
43474396
yields a pointer of type ``pointer to \cv{}~\tcode{T}''.

0 commit comments

Comments
 (0)