为什么说C++不支持参数多态?

Why is C++ said not to support parametric polymorphism?

根据 Parametric Polymorphism 的维基百科页面:

Some implementations of type polymorphism are superficially similar to parametric polymorphism while also introducing ad hoc aspects. One example is C++ template specialization.

问题:为什么说 C++ 只实现表面上类似于参数化多态的东西?特别是,模板不是完全参数化多态性的例子吗?

您链接到的文章对此进行了解释。您引用的文字实际上给出了一个将 C++ 模板与纯参数多态性区分开来的示例:C++ 模板专业化。

它继续这个主题:

Following Christopher Strachey,[2] parametric polymorphism may be contrasted with ad hoc polymorphism, in which a single polymorphic function can have a number of distinct and potentially heterogeneous implementations depending on the type of argument(s) to which it is applied. Thus, ad hoc polymorphism can generally only support a limited number of such distinct types, since a separate implementation has to be provided for each type.

因此,如前所述,C++ 模板接近——但不完全是——参数多态性。

Why is C++ said to only implement something superficially similar to parameterized polymorphism? In particular, aren't templates an example of full on parametric polymorphism?

C++中的模板化函数在"substitution"参数的基础上工作。这实质上意味着编译器会生成另一个版本的函数,其中模板参数被硬编码到函数中。

假设你在 C++ 中有这个:

template <typename T>
T add(T a, T b) {
    return a + b;
}

int main() {
    int i = add(2, 3);
    double d = add(2.7, 3.8);
    return i + (int)d;
}

在编译期间,这将产生两个函数:int add(int a, int b) { return a + b; }double add(double a, double b) { return a + b; } 一个函数将只处理整数,另一个将只处理双精度数。没有多态性。

实际上,您最终会得到与参数变体数量一样多的实现。

"但为什么不是参数多态性?"你可能会问?

您需要 'add' 函数的完整源代码,以便使用您自己的特定变体来调用它,从而重载二进制“+”运算符! - 这就是 细节的不同之处。

如果 C++ 具有适当的参数多态性,例如 C#,那么 'add' 的最终编译实现将包含足够的逻辑来确定在运行时对于 'add'。你不需要那个函数的源代码,用你发明的新类型调用它。

这在现实中意味着什么?

但不要将此理解为好像 C++ 不那么强大或 C# 更强大。它只是众多语言功能细节之一。

如果您拥有可用于模板化函数的完整源代码,那么 C++ 的语义要优越得多。如果您只有一个静态或动态库供您使用,那么参数化多态实现(例如 C#)更胜一筹。