我很好奇Scala和C ++ 11的类型推断之间的区别是什么。在哪种情况下,我必须用一种语言指定类型而不是另一种语言?一个区别似乎是函数的返回类型总是必须在C ++ 11中指定,尽管decltype
和具有尾随返回类型的新函数语法允许指定推断类型。
答案 0 :(得分:10)
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 ++代码语法,我不会侮辱语言,但它真的很神秘。如果我犯了错误,请纠正我,
答案 1 :(得分:9)
从本质上讲,与成年人相比,C ++推理是简单的。
功能语言通常接近于 Hindley / Milner ,它非常接近于解决方程式系统并允许在栅栏的两侧都有未知数。
相反,C ++希望能够知道任何内部表达式的类型,并从中推断出外部表达式的类型。这是一种严格的单向推理,意思是:
auto x = foo(1, 2);
只要有foo
接受整数并返回非void,就可以正常工作。但是,如om-nom-nom所示:
foo(1, [](auto x) { ++x; });
不会起作用,因为你不能后退并使用声称的foo
类型来推断lambda的类型。
背后的原因是C ++使用了函数的重载,这意味着可能存在foo
的几个定义,并且您实际上需要知道选择正确参数的类型。因为一般来说上面的表达是不可判定的,所以即使在有限的情况下也可以禁止它,以避免将来的维护地狱,人们永远不知道它何时可以被使用。