推断类型的模板和隐式类型转换有什么问题?

What is wrong with inferred type of template and implicit type conversion?

我正在阅读 Andrei Alexandrescu 的 "The D Programming Language",有一句话让我感到困惑。考虑这样的代码(第 138 页):

T[] find(T)(T[] haystack, T needle) {
   while (haystack.length > 0 && haystack[0] != needle) {
      haystack = haystack[1 .. $];
   }
   return haystack;
}

并调用 (p.140):

double[] a = [ 1.0, 2.5, 2.0, 3.4 ];
a = find(a, 2); // Error! ' find(double[], int)' undefined

说明(代码下方段落):

If we squint hard enough, we do see that the intent of the caller in this case was to have T = double and benefit from the nice implicit conversion from int to double. However, having the language attempt combinatorially at the same time implicit conversions and type deduction is a dicey proposition in the general case, so D does not attempt to do all that.

我很困惑,因为像 C# 这样的语言试图推断类型——如果它不能这样做,用户就会收到错误,但如果可以,那么它就可以工作。 C# 与它共存了好几年,但我没有听到任何关于此功能如何毁掉某人一天的故事。

所以我的问题是 — 如上例所示,推断类型涉及哪些危险?

我只能看到优点,泛型函数很容易写,也很容易调用。否则,您将不得不在泛型 class/function 中引入更多参数,并编写特殊约束来表达允许的转换,只是为了推断类型。

首先要注意的是不是说类型推导有问题,是类型推导有问题隐式转换同时.

因此,如果您有:

a = find(a, 2.0);

然后很高兴推导出double类型

如果显式键入 double,很高兴推断出 2 应该隐式转换为 2.0

它不会同时进行。

现在,C# 确实做到了。而且我认为在很大程度上我同意你的看法,它通常很方便并且通常运行良好。

同时它确实会造成混淆,尤其是在它导致不止一个同样合理的过载的情况下。

Why type inference and implicit operator is not working in the following situations? and 都是关于为什么隐式转换和类型推断的特定组合不起作用的问题。

Unexpected effect of implicit cast on delegate type inference 还有其他因素,但再次拒绝考虑可能匹配列表中的方法,因为参数类型不匹配将意味着问题没有发生。

如果答案总是"because you are doing implicit conversion and type inference at the same time, and that's not supported",它们都会简单得多。这就是 D.

的答案

但另一方面,此类问题并不经常出现,因此我仍然赞成 C# 设计决定允许这两种情况,但存在一些问题意味着不允许它们仍然是一个合理的设计决定.