From §4.2.7 of the proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html#pathological-cases
It said that:
These are even more unlikely to be actually useful code. In this example,
Bis neither convertible toAnorint, so neither of these functions is even invocable using normal member syntax. However, you could take a pointer to such functions and invoke them through that pointer.(&B::bar)(42)is valid, if weird, call.
However, It does not specify whether the standard does not allow explicit object parameter of type-of-self implicitly convertible to particular another type.
struct A { };
struct B {
void foo(this A&);
void bar(this int);
};
Does that mean that:
struct A { };
struct B {
operator A() const noexcept;
void foo(this A);
};
// ...
// '&B::foo' is of type function pointer not pointer to member function
// because it uses explicit object parameter.
(&B::foo)(A{});
(&B::foo)(B{});
B{}.foo(); // will work?
will work?
In another case, here is a lambda. Since the type of the lambda is unutterable and is always dependent. What about the case above? (this captureless lambda is convertible to int(*)(int, int, int))
auto fib = [](this int(* self)(int, int, int), int n, int a = 0, int b = 1) {
return n == 0 ? a : n == 1 ? b : self(n - 1, b, a + b);
};
Given that:
Non-member functions, static member functions, and explicit object member functions match targets of function pointer type or reference to function type. Non-static Implicit object member functions match targets of pointer-to-member-function type. ([over.match.viable] §12.2.3)
In all contexts, when converting to the implicit object parameter or when converting to the left operand of an assignment operation only standard conversion sequences are allowed. [Note: When converting to the explicit object parameter, if any, user-defined conversion sequences are allowed. - end note ] ([over.best.ics] §12.2.4.2)