struct A {
int i;
template <std::convertible_to<A> Other> A& operator=(Other&& other) {
using A_cvref = copy_cvref_t<Other&&, A>;
i = static_cast<A_cvref>(other).i;
return *this;
}
};
This isn't equivalent to the first thing Phil wrote; it'll never generate
A volatile & operator = (A const & a) volatile { i = a.i; return * this; }
On the other hand, the second thing Phil wrote is also completely different from the first thing Phil wrote. Phil's second thing—
template <qualifier Q, qualifier P>
A Q & operator = (A P a) Q { i = std::move_or_copy(a.i); return * this; }
—seems like it would happily generate signatures such as `A const& operator=(A volatile a) const`. And no substitution for `P` and `Q` could ever generate the signature `A& operator= (A const& a)`, unless `P` is allowed to be `const&` (but then how would deduction know to make it `const&` instead of simply `const` or nothing-at-all)?
Phil seems to maybe be treating "&" and "&&" as possible values for a `qualifier`, I'm not sure.
Phil also seems to be treating "the-absence-of-anything" as a possible value for a `qualifier`.
I agree that any proposal which has been technically fleshed out (such as P0847) is in some sense preferable to a vague, non-technical, and unimplementable musing. However, it's also comparing apples to oranges.
–Arthur