还有哪些其他语言支持“部分专业化”?
部分模板特化是 C++ 泛型编程最重要的概念之一。 例如:实现通用交换函数:
template <typename T>
void swap(T &x, T &y) {
const T tmp = x;
y = x;
x = tmp;
}
将其专门化为向量以支持 O(1) 交换:
template <typename T, class Alloc>
void swap(vector<T, Alloc> &x, vector<T, Alloc> &y) { x.swap(y); }
因此,当您在通用函数中调用 swap(x, y) 时,始终可以获得最佳性能;
如果您可以用替代语言发布等效内容(或者如果该语言不支持交换概念,则该语言的部分专业化的规范示例),我们将不胜感激。
编辑:所以看起来很多回答/评论的人真的不知道什么是部分专业化,并且通用交换示例似乎妨碍了某些人的理解。 一个更一般的例子是:
template <typename T>
void foo(T x) { generic_foo(x); }
部分专业化是:
template <typename T>
void foo(vector<T> x) { partially_specialized_algo_for_vector(x); }
完全专业化是:
void foo(vector<bool> bitmap) { special_algo_for_bitmap(bitmap); }
为什么这很重要? 因为您可以在通用函数中调用 foo(anything):
template <typename T>
void bar(T x) {
// stuff...
foo(x);
// more stuff...
}
并在编译时获得最合适的实现。 这是 C++ 以最小的性能损失实现抽象的一种方法。
希望它有助于理清“部分专业化”的概念。 在某种程度上,这就是 C++ 进行类型模式匹配的方式,而不需要显式模式匹配语法(例如 Ocaml/F# 中的 match 关键字),这有时会妨碍泛型编程。
Partial template specialization is one of the most important concepts for generic programming in C++. For example: to implement a generic swap function:
template <typename T>
void swap(T &x, T &y) {
const T tmp = x;
y = x;
x = tmp;
}
To specialize it for a vector to support O(1) swap:
template <typename T, class Alloc>
void swap(vector<T, Alloc> &x, vector<T, Alloc> &y) { x.swap(y); }
So you can always get optimal performance when you call swap(x, y) in a generic function;
Much appreciated, if you can post the equivalent (or the canonical example of partial specialization of the language if the language doesn't support the swap concept) in alternative languages.
EDIT: so it looks like many people who answered/commented really don't known what partial specialization is, and that the generic swap example seems to get in the way of understanding by some people. A more general example would be:
template <typename T>
void foo(T x) { generic_foo(x); }
A partial specialization would be:
template <typename T>
void foo(vector<T> x) { partially_specialized_algo_for_vector(x); }
A complete specialization would be:
void foo(vector<bool> bitmap) { special_algo_for_bitmap(bitmap); }
Why this is important? because you can call foo(anything) in a generic function:
template <typename T>
void bar(T x) {
// stuff...
foo(x);
// more stuff...
}
and get the most appropriate implementation at compile time. This is one way for C++ to achieve abstraction w/ minimal performance penalty.
Hope it helps clearing up the concept of "partial specialization". In a way, this is how C++ do type pattern matching without needing the explicit pattern matching syntax (say the match keyword in Ocaml/F#), which sometimes gets in the way for generic programming.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
D 支持部分专业化:
(扫描上述链接中的“部分”)。
特别是第二个链接将为您提供非常详细的细分,说明您可以使用模板专业化做什么,不仅在 D 中,而且在 C++ 中也是如此。
这是
交换
的 D 特定示例。 它应该打印出专门用于Thing
类的交换消息。D supports partial specialization:
(scan for "partial" in the above links).
The second link in particular will give you a very detailed breakdown of what you can do with template specialization, not only in D but in C++ as well.
Here's a D specific example of
swap
. It should print out the message for the swap specialized for theThing
class.恐怕 C# 不支持部分模板特化。
部分模板专业化意味着:
您有一个带有两个或多个模板(泛型/类型参数)的基类。。
类型参数将是
在派生(专用)类中,您可以指示类型参数之一的类型。。
类型参数可能类似于
因此,当有人使用最后一个类型参数为 int 的类(实例化其对象)时,将使用派生类。
I am afraid that C# does not support partial template specialization.
Partial template specialization means:
You have a base class with two or more templates (generics / type parameters).
The type parameters would be <T, S>
In a derived (specialized) class you indicate the type of one of the type parameters.
The type parameters could look like this <T, int>.
So when someone uses (instantiates an object of) the class where the last type parameter is an int, the derived class is used.
Haskell 有重叠实例作为扩展:
是一个查找任何集合大小的函数,它可以有更具体的实例:
另请参阅 HaskellWiki 上的高级重叠。
Haskell has overlapping instances as an extension:
is a function to find size of any collection, which can have more specific instances:
See also Advanced Overlap on HaskellWiki.
实际上,您可以(不完全是;见下文)使用扩展方法在 C# 中执行此操作:
然后调用 array.Count() 将使用专用版本。 “不完全是”是因为解析取决于数组的静态类型,而不是运行时类型。 即这将使用更通用的版本:
Actually, you can (not quite; see below) do it in C# with extension methods:
Then calling
array.Count()
will use the specialised version. "Not quite" is because the resolution depends on the static type ofarray
, not on the run-time type. I.e. this will use the more general version:C#:
我猜(纯)Haskell 版本是:
C#:
I guess the (pure) Haskell-version would be:
Java 有泛型,它允许您做类似的事情。
Java has generics, which allow you to do similar sorts of things.