検討:
#include <cstdlib>
class Bar {};
class Foo
{
public:
Foo (Bar& bar)
:
mBar (bar)
{
}
const Bar& get() const
{
return mBar;
}
private:
Bar& get()
{
return mBar;
}
Bar& mBar;
};
int main()
{
Bar bar;
Foo foo (bar);
Bar& ref = foo.get();
}
呼び出しの時点で:参照を割り当てているため、 のバージョンが呼び出されるとconst Bar& ref = foo.get();
予想される場合があります。const
get()
const
しかし、そうではありません。戻り値の型は関数 (またはメソッド) のシグネチャの一部ではないため、コンパイラが可能なオーバーロードのリストで呼び出す関数を探すとき、戻り値の型は考慮されません。(実際、標準は、戻り値の型だけが異なる関数のオーバーロードを拒否します。)
では、コンパイラはどの関数を呼び出すかをどのように決定するのでしょうか? 情報を見ることによって、それは利用可能です。2 つのオーバーロードはパラメーターに関しては同一であるため (どちらもvoid
)、実行する必要があるのは、呼び出しを行うために使用されるオブジェクトの静的な型だけです: foo
. この場合の静的型はFoo
-- 明らかに non-const
です。
したがって、それができる唯一の関数を呼び出そうとしました: の非const
バージョンですget()
。もちろん、これはコンパイルされませんprivate
。
const Foo
これをフォックスするために、次のように静的タイプを a (または同様のもの) に変更できます。
Foo foo (bar);
Bar& ref = foo.get();
または多分...
Foo foo (bar);
const Bar& ref = static_cast <const Foo&> (foo).get();
しかし、実際には、これらの関数の名前はあいまいではないことをお勧めします。このような「トリック」に頼ってコンパイラをねじ曲げて、必要なことを実行させるのではありません。