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

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

本文关键字:参数 多态性 不支持 C++ 为什么      更新时间:2023-10-16

根据参数多态性的维基百科页面:

类型多态性的一些实现表面上类似于参数多态性,同时也引入了特定方面。一个例子是C++模板专门化。

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

您链接到的文章解释了这一点。你引用的文本实际上给出了一个例子,说明C++的模板与纯参数多态性不同:C++模板专业化。

它继续这个主题:

继Christopher Strachey之后,[2]参数多态性可以与特设多态性进行对比,在特设多态性中,单个多态函数可以具有许多不同的潜在异构实现,这取决于它所应用的参数类型。因此,特设多态性通常只能支持有限数量的这种不同类型,因为必须为每种类型提供单独的实现。

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

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

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

假设你在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; }一个函数将仅处理int,另一个函数仅处理double。无多态性。

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

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

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

如果C++具有适当的参数多态性,例如C#,那么"add"的最终编译实现将包含足够的逻辑,以在运行时确定"add"可接受的任何给定参数的"+"重载。而且你不需要这个函数的源代码,就可以用你发明的新类型来调用它。

这在现实中意味着什么

但不要把这理解为C++的功能较弱或C#的功能更强。这只是众多语言功能细节中的一个。

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