来自提案的§4.2.7 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html#pathological-cases
它说:
这些更不可能是真正有用的代码。在此示例中,
B
既不能转换为A
也不能int
,因此这些函数都不能使用正常的成员语法调用。但是,您可以获取指向此类函数的指针并通过该指针调用它们。(&B::bar)(42)
是有效的,如果奇怪,打电话。
但是,它没有指定标准是否不允许显式的自我类型的对象参数隐式转换为特定的另一种类型。
struct A { };
struct B {
void foo(this A&);
void bar(this int);
};
这是否意味着:
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?
将工作?
在另一种情况下,这里是一个 lambda。因为 lambda 的类型是不可言说的并且总是依赖的。上面的案例呢?(这个无捕获的 lambda 可以转换为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);
};
鉴于:
非成员函数、静态成员函数和显式对象成员函数匹配函数指针类型的目标或对函数类型的引用。非静态隐式对象成员函数匹配指向成员函数类型的目标。([over.match.viable] §12.2.3)
在所有上下文中,当转换为隐式对象参数或转换为赋值操作的左操作数时,仅允许标准转换序列。[注意:当转换为显式对象参数时,如果有的话,用户定义的转换序列是允许的。- 尾注]([over.best.ics] §12.2.4.2)