質問
戻り値の型にポリモーフィズムを持つ呼び出し可能オブジェクトを許可するCのような言語が表示されないのはなぜですか?追加の型推論がどのようにハードルになるかはわかりましたが、多数の言語があります本格的な型推論システム(さまざまなレベルの「作業」で機能します)。
編集:戻り型のポリモーフィズムとは、戻り型でのみ関数シグネチャをオーバーロードすることを意味します。たとえば、C ++およびJavaでは、戻り値の型ではなく、仮パラメータの型でのオーバーロードのみが許可されます。
解決
「戻り型ポリモーフィズム」による場合あなたは戻り値の型に基づいてオーバーロードを意味しますが、他の言語についてはわかりませんが、C ++の場合は答えがあります(ほとんど馬の口から):
単純にStroustrup(他のC ++アーキテクトからの入力を前提としている)がオーバーロードの解決を「コンテキスト非依存」にしたかったため、関数の戻り値の型はオーバーロードの解決に関与しません。 7.4.1-「オーバーロードと戻り値の型」を参照してください。 「C ++プログラミング言語、第3版」から。
理由は、 個々の演算子または関数 コンテキストに依存しないで呼び出します。
彼らは、結果がどのように使用されたかではなく、オーバーロードが呼び出された方法のみに基づいていることを望んでいました(使用された場合)。実際、結果を使用せずに多くの関数が呼び出されるか、結果がより大きな式の一部として使用されます。彼らがこれを決定したときに確実に出てきた1つの要因は、戻り値の型が解決の一部である場合、複雑なルールで解決する必要があるか、コンパイラーをスローする必要があるオーバーロードされた関数への多くの呼び出しがあることでした呼び出しがあいまいだったというエラー。
そして、C ++のオーバーロードの解決は現状のままで十分に複雑であると、主は知っています...
他のヒント
iは、関数fooがdoubleまたはintまたは文字列を返すことができるだけでなく、fooが異なるクラスの構造体またはオブジェクトを返すことができるように、この機能をある言語で見たいと思っています。呼び出しの明確化はかなり簡単です。呼び出しがあいまいな場合は、キャストを使用して目的の戻り値の型を選択する必要があります。例:
string s = foo(); //foo returns a string
double x = foo(); //foo returns a double
int i = foo(); //foo returns an integer
float f = (float)(int)foo(); //call the int foo and convert to float
さらに
Animal a = fooFactory(); //fooFactory returns an Animal
Plant p = fooFactory(); //foofactory returns a Plant
これらの状況はそれほど頻繁に発生するわけではありませんが、回避策を実行すると、かなりugい場合が多い...
double x = (double)foo();
double、int、floatなどを返すことができるfoo()のバージョンがある場合、上記はあいまいです。
C ++では、クラスを使用してこれを大幅に行うことができます。たとえば、入力と出力で日常的にASCIIに変換されるデータ型があるとします;
typedef char* pchar;
class MyType
{
public:
operator pchar() { return(ConvertToASCII()); }
MyType& operator=(char* input) { ConvertFromASCII(input); return(*this); }
pchar ConvertToASCII();
void ConvertFromASCII(pchar ASCII);
}
このタイプのものは、C ++フレームワークでよく使用されます。たとえば、MFC CStringクラスの実装を見てください。私見、それは特定の状況では危険ですが、非常に便利なツールです。
型の自動変換のため、戻り値の型が近いときにどの関数を呼び出すかを知ることは明らかではありません。