確かに、オーバーロードの解決はアクセシビリティ チェックの前に行われます。標準のセクション 13.3 ( [over.match]) は次のように述べています。
オーバーロードの解決は、呼び出しの引数となる式のリストと、呼び出しのコンテキストに基づいて呼び出すことができる候補関数のセットが与えられた場合に、呼び出すのに最適な関数を選択するためのメカニズムです。最適な関数の選択基準は、引数の数、引数が候補関数のパラメーターの型リストとどの程度一致するか、(非静的メンバー関数の場合) オブジェクトが暗黙的なオブジェクト パラメーターとどの程度一致するか、およびその他の特定のものです。候補関数のプロパティ。[注: オーバーロードの解決によって選択された関数は、コンテキストに適しているとは限りません。関数のアクセシビリティなどのその他の制限により、呼び出しコンテキストでの使用が不適切になる可能性があります。— エンドノート]
通常の修正は、公開関数と保護関数に別の名前を付けることです。
これは時々役立つことに注意してください。例:
class Blah
{
const std::string& name_ref;
Blah(const char*) = delete;
public:
Blah(const std::string& name) : name_ref(name) {}
void do_something_with_name_ref() const;
};
std::string s = "Blam";
Blah b(s); // ok
name_refからのみ読み取られることに注意してくださいconst。ただし、const参照は一時オブジェクトにバインドできます。一時オブジェクトにバインドするname_refと、ダングリング参照になり、 で未定義の動作が発生しdo_something_with_name_ref()ます。
Blah c("Kablooey!"); // would be undefined behavior
// the constructor overload makes this a compile error
プライベート コンストラクターのオーバーロードは、一時的なstd::stringコンストラクターが暗黙的に構築およびバインドされるのを防ぎます。