这种理解是否正确:特征和函数重载都实现了临时多态性,但方向不同

Is this understanding correct: trait and function overloading both achieved ad hoc polymorphism but in different direction

我正在学习一些多态性。

rust 地址的 wiki 页面 traitmethod to achieve ad hoc polymorphism, and the page for ad hoc polymorphismfunction overloading 是临时多态性的一个例子。

根据我目前的理解水平,如果提供不同类型的参数将调用不同的实现,则函数是临时多态的。但是 traitfunction overloading 看起来很不一样: trait 对类型参数添加约束,任何类型实现 trait 都是可以接受的,而函数重载在具体类型上重载,任何类型没有超载的是不可接受的。

我可以说 traitfunction overloading 在相反的方向上实现了临时多态性吗? trait 是专业化而 overloading 是泛化?

PS: 在c++中,模板特化也可以根据传入的类型参数提供不同的实现,这也是ad hoc多态的一个例子吗?

实现特征涉及提供行为的实现,它是特定于类型的并且与其他实现(“临时”)分开,并且可以在调用站点使用与其他实现相同的拼写来调用(“多态”)。和函数重载方向一致

在 C++ 中,您可以提供重载来实现临时多态性:

void foo(const X&) { ... }
void foo(const Y&) { ... }
// can call foo(z) where z is an X or a Y

你可以对 Rust 中的特征做同样的事情:

trait Foo { fn foo(); }
impl Foo for X { ... }
impl Foo for Y { ... }
// can call z.foo() where z is an X or a Y

我认为您指的“另一个方向”是能够通过类型支持的行为来限制泛型。在 Rust 中,这看起来像:

fn bar<T: Foo>(t: T) { ... }
// bar can use t.foo()

C++有个类比:

template<typename T> concept Foo = requires(T t) { foo(t); };
void bar(Foo auto& t) { ... }
// bar can use foo(t)
// (this uses really new C++, it's written differently in older C++)

受约束的泛型函数不是临时多态性,因为它们有一种实现适用于所有参数类型,这些参数类型实现了对它们的任何要求。

总而言之,traits 为泛型函数提供了特殊的多态性和约束,一些语言(如 C++)使用不同的设备来实现相同的目的。 C++ 中的临时多态性通常通过函数重载来实现。模板特化也可以实现。