在Rust中,与C++中特定模板用法相当的是什么?

8
有没有Rust中类似这样的功能? 据我所知,使用Rust的通用函数是不可能实现这一点的,因为它们只能使用数据类型而不能使用值。
#include <iostream>

template<int T>
int foo(int a)
{
  return -1;
}
template<>
int foo<2>(int a)
{
  return a*a;
}
template<>
int foo<3>(int a)
{
  return a*a*a;
}

int main()
{
  std::cout << "foo<1>(3): "<<foo<1>(3) << std::endl;
  std::cout << "foo<2>(3): "<<foo<2>(3) << std::endl;
  std::cout << "foo<3>(3): "<<foo<3>(3) << std::endl;
  return 1;
}

结果:

foo<1>(3): -1
foo<2>(3): 9
foo<3>(3): 27

1个回答

14

TL;DR: 目前还不行,也许永远都不会。

目前 Rust 的泛型系统还没有 C++ 模板强大,而且可能永远也不会有这样的能力。

具体来说,需要两个特性:

注意:还不清楚专业化(specialization)的成熟程度,对于使用完全专业化(full specialization)的情况,它足够了,但不清楚是否实现部分专业化(partial specialization),以及如何实现。


还有其他缺失的部分,虽然与此案例无关:

  • RFC 1598: Generic Associated Types:相当于嵌套的 template <...> using ... = ...; 并允许模拟模板模板参数,
  • 可变参数:已经有多个 RFC,但似乎没有赢得太多支持。

很容易嘲笑 Rust 开发者,或者将其视为不成熟的表现;但这是错误的。

正如我提到的,Rust 可能永远不会具备某些特性,不是因为开发者不能实现它们,他们当然可以,他们甚至本来就可以实现,而是因为有一个强调做正确的事情1

例如在C++中,模板的特化是一个噩梦。使用一组参数A实例化模板,然后以在另一个翻译单元或稍后匹配A的方式进行特化将导致未定义行为。对于函数来说,这通常表现为链接器随机选择通用或专门的版本...... 调试起来很不好玩。
对泛型代码的任何修改都可能对类型系统的其余部分产生重大影响,与其他语言功能的复杂交互,并且显着改变了良好类型化程序的含义:
- 因此,它们受到密切审查, - 并且有强烈的推动朝着“慢”和逐步构建的方向发展,以便逐个评估这些影响、交互和更改。
简而言之,Rust开发人员正试图构建一个有原则的泛型系统,这并不容易。
PS:还有关于不必要复杂性的担忧,因此不会“仅仅因为”添加功能,而需要有充分的理由来证明该功能在语言和编译器中增加复杂度的合理性;但那是另一个完全不同的问题。

@Stefan:谢谢,我漏看了这个。 - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接