Scala和C++ 11的类型推断有什么区别?

Fra*_*mas 17 c++ scala type-inference language-comparisons c++11

我很好奇Scala和C++ 11的类型推断之间的区别是什么.在哪种情况下,我必须用一种语言指定类型而不是另一种语言?一个区别似乎是函数的返回类型总是必须在C++ 11中指定,尽管decltype具有尾随返回类型的新函数语法允许指定推断类型.

om-*_*nom 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
Run Code Online (Sandbox Code Playgroud)

而斯卡拉可以:

def somefunc(v: Vector[Int]) = v.map(x => x +1)
Run Code Online (Sandbox Code Playgroud)

*不确定我是否正确使用了C++代码语法,我不会侮辱语言,但它真的很神秘.如果我犯了错误,请纠正我

  • 您正在将向量上的方法调用与函数进行比较.等效的Scala方法应该看起来像`map(v,x => x + 1)`(使用适当的`map`方法).在这种情况下,Scala的推理也失败了.但是,这将起作用:`map(v)(x => x + 1)`. (3认同)
  • 在C++示例中,`x`的类型可以由`decltype(*v.begin())`指定,请参阅:http://stackoverflow.com/a/5713038/460387但这也不是类型推断.. . (2认同)

Mat*_* M. 9

从本质上讲,与成年人相比,C++推理是简单的.

函数式语言通常接近于Hindley/Milner,它非常接近求解方程系统并允许在栅栏的两侧都有未知数.

相反,C++期望能够知道任何内部表达式的类型,并从中推断出外部表达式的类型.这是一种严格的单向推理,意味着:

auto x = foo(1, 2);
Run Code Online (Sandbox Code Playgroud)

只要有一个foo接受整数并返回非void,就可以正常工作.但是,如om-nom-nom所示:

foo(1, [](auto x) { ++x; });
Run Code Online (Sandbox Code Playgroud)

将无法工作,因为你不能后退并使用声称的类型foo来推断lambda的类型.

背后的原因是C++使用了函数的重载,这意味着foo可能存在多个定义,并且您实际上需要知道选择正确参数的类型.由于一般来说上述表达方式是不可判定的,所以即使在有限的情况下也可以禁止它以避免将来的维护地狱,并且人们永远不知道它何时可以被使用.

  • 是吗 ?我会说不.C++类型推断是最简单的推理.它很有用,但与Hindley/Milner相比肯定是简单的. (7认同)
  • 为了对比C++ 11和Scala:Scala也进行方法重载(并且不使用Hindley-Milner). (4认同)
  • 你说C++的推理与'grow ups'相比是简单化的,但你用来证明这个的语法:`foo(1,[](auto x){++ x;});`已经很好理解了,C++的推论没有处理它需要任何额外的复杂性.今天你可以准确地表达lambda的建议含义,而C++会很好地处理它. (3认同)