@ Lol4t0はかなり正しいと思いますが、もっと強く述べたいと思います。これを許可した場合、2つの可能性があります。言語のほぼ全体にわたって他の多くの変更を行うか、またはほぼ完全に壊れたものになってしまいます。
これを機能させるために行うその他の変更は、オーバーロードの実行方法を完全に刷新することです。少なくとも、実行されたステップの順序、およびおそらくステップ自体の詳細を変更する必要があります。現在、コンパイラは名前を検索し、オーバーロードセットを形成し、オーバーロードを解決してから、選択したオーバーロードへのアクセスをチェックします。
これをうまく機能させるには、最初にアクセスをチェックするように変更し、アクセス可能な関数のみをオーバーロードセットに追加する必要があります。これにより、少なくとも@ Lol4t0の回答の例は、オーバーロードセットに追加されることはないため、コンパイルを続行できます。Base::foo
ただし、それでも、基本クラスのインターフェースに追加すると、深刻な問題が発生する可能性があることを意味します。Base
もともと含まれていなかった場合foo
、パブリック が追加された場合、へfoo
の呼び出しは突然まったく異なることを行い、(再び)それは誰が書いたのか完全に制御できなくなります。main
d.foo()
Derived
これを解決するには、ルールにかなり根本的な変更を加える必要があります。関数の引数の暗黙的な変換を禁止します。それに加えて、オーバーロードの解決を変更するので、同点の場合は、関数の最も派生した/最もローカルなバージョンが、あまり派生していない/外部のスコープよりも優先されました。これらのルールでは、への呼び出しはそもそも解決d.foo(5.0)
できませんでした。Derived::foo(int)
ただし、それは2つの可能性しか残しません。free関数の呼び出しはメンバー関数の呼び出しとは異なるルールを持つか(free関数に対してのみ暗黙の変換が許可されます)、そうでない場合はCとのすべての互換性が完全に破棄されます(つまり、暗黙の変換も禁止されます)。すべての関数の引数で、既存のコードの膨大な量を壊してしまいます)。
要約すると、言語を完全に壊すことなくこれを変更するには、他にもかなりの数の変更を加える必要があります。そのように機能する言語を作成することはほぼ確実に可能ですが、それが完了するまでには、1つの小さな変更を加えたC ++ではなく、C++やCとはあまり似ていないまったく異なる言語になります。、または他の多くのもの。