Date: Wed, 28 Dec 2022 10:54:27 -0500
On Wed, Dec 28, 2022 at 7:14 AM Lénárd Szolnoki via Std-Discussion
<std-discussion_at_[hidden]> wrote:
> I don't think you get an automatic operator& that is accessible with
> the .operator&() syntax. `&u` and `&move(u)` is differrent.
Indeed. The syntax E.operator@() can only resolve to member functions
of E's class. The only implicitly-declared member functions are the
copy assignment operator, the move assignment operator, and the
operator== function implicitly declared for each operator<=> function
defined as defaulted (11.10.1 [class.compare.default] para. 4). But
ordinary operator expressions are subject to overload resolution which
includes built-in candidates and rewritten candidates.
To expand on the difference between &d and &move(d) which makes only
the former valid:
Dog::operator& is not a viable function for &d, since there is no
implicit conversion sequence which converts lvalue d to type const
volatile Dog&&. Since there are no viable functions, 12.2.2.3
[over.match.oper] paragraph 13 applies: "If the operator is the
operator ,, the unary operator &, or the operator ->, and there are no
viable functions, then the operator is assumed to be the built-in
operator and interpreted according to 7.6." Therefore, &d is
interpreted as the built-in & operator.
Meanwhile, Dog::operator& is a viable function for &move(d), since a
reference of type const volatile Dog&& can bind directly to xvalue
move(d). Therefore, overload resolution selects Dog::operator& for
&move(d), resulting in an error, since the function is defined as
deleted.
<std-discussion_at_[hidden]> wrote:
> I don't think you get an automatic operator& that is accessible with
> the .operator&() syntax. `&u` and `&move(u)` is differrent.
Indeed. The syntax E.operator@() can only resolve to member functions
of E's class. The only implicitly-declared member functions are the
copy assignment operator, the move assignment operator, and the
operator== function implicitly declared for each operator<=> function
defined as defaulted (11.10.1 [class.compare.default] para. 4). But
ordinary operator expressions are subject to overload resolution which
includes built-in candidates and rewritten candidates.
To expand on the difference between &d and &move(d) which makes only
the former valid:
Dog::operator& is not a viable function for &d, since there is no
implicit conversion sequence which converts lvalue d to type const
volatile Dog&&. Since there are no viable functions, 12.2.2.3
[over.match.oper] paragraph 13 applies: "If the operator is the
operator ,, the unary operator &, or the operator ->, and there are no
viable functions, then the operator is assumed to be the built-in
operator and interpreted according to 7.6." Therefore, &d is
interpreted as the built-in & operator.
Meanwhile, Dog::operator& is a viable function for &move(d), since a
reference of type const volatile Dog&& can bind directly to xvalue
move(d). Therefore, overload resolution selects Dog::operator& for
&move(d), resulting in an error, since the function is defined as
deleted.
Received on 2022-12-28 15:54:39