ScalaとC++11の型推論の違いが何であるか興味があります。どのような状況で、一方の言語でタイプを指定する必要がありますが、もう一方の言語では指定する必要はありませんか?1つの違いは、C ++ 11で常に指定する必要がある関数の戻り型であるように見えdecltype
ますが、末尾の戻り型を持つ新しい関数構文では、推論された型を指定できます。
2 に答える
C++ は、そのような無名関数を推論できません。
// this wont work*
void somefunc(std::vector<int>& v)
{
std::for_each(v.begin(), v.end(), [](auto &x) { x++; });
}
// /\
// ------ I want this to be infered
一方、Scala は次のことができます。
def somefunc(v: Vector[Int]) = v.map(x => x +1)
* C++ コードの構文を正しく扱ったかどうかはわかりません。言語を侮辱しているわけではありませんが、それは本当に難解です。私が間違いを犯した場合は、私を修正してください
本質的に、C++ の推論は大人に比べて単純です。
関数型言語は、一般にHindley/Milnerに近いもので、方程式系を解くのに非常に近く、フェンスの両側に未知数を持つことができます。
それどころか、C++ は内部式の型を認識し、そこから外部式の型を推測できることを期待しています。これは厳密に一方向の推論であり、次のことを意味します。
auto x = foo(1, 2);
foo
整数を受け入れ、非 void を返す限り、期待どおりに動作します。ただし、om-nom-nom によって示されるように:
foo(1, [](auto x) { ++x; });
foo
戻って、ラムダの型を推測するために、目的の型を使用することはできないため、機能しません。
その背後にある理由は、C++ が関数のオーバーロードを使用するためです。つまり、いくつかの定義foo
が存在する可能性があり、正しいものを選択するには引数の型を実際に知る必要があります。一般的に上記の表現は判断がつかないので、将来のメンテナンス地獄やいつ使えるか分からない人を避けるために限られた場合でも禁止します。