提案の§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?
動作します?
別のケースでは、これがラムダです。ラムダの型は発話不可能であり、常に依存しているためです。上記の場合はどうでしょうか。(このキャプチャレス ラムダは に変換可能です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)