可能重复:
What are the differences between Generics in C# and Java… and Templates in C++?
C#泛型与C ++模板之间有什么区别?我明白他们并没有解决完全相同的问题,那么两者的优点和缺点是什么?
答案 0 :(得分:20)
您可以将C ++模板视为一种伪装成泛型系统的解释型函数式编程语言。如果这不会吓到你,它应该:)
C#泛型非常有限;您可以参数化一个或多个类型的类,并在方法中使用这些类型。因此,要从MSDN中获取示例,您可以执行以下操作:
public class Stack<T>
{
T[] m_Items;
public void Push(T item)
{...}
public T Pop()
{...}
}
现在你可以声明Stack<int>
或Stack<SomeObject>
并且它会安全地存储该类型的对象(即,不担心错误地放入SomeOtherObject
)。
在.NET内部,.NET运行时会将其专门化为基本类型(如int)的变体,以及对象类型的变体。例如,这允许Stack<byte>
的表示远小于Stack<SomeObject>
的表示。
C ++模板允许类似的用途:
template<typename T>
class Stack
{
T *m_Items;
public void Push(const T &item)
{...}
public T Pop()
{...}
};
乍一看看起来很相似,但有一些重要的区别。首先,对于每个基本类型而不是一个变体,而不是每个基本类型都有一个变体,每个类型都有一个变体,它是针对实例化的。这可能是很多类型!
下一个主要区别是(在大多数C ++编译器上)它将在它使用的每个翻译单元中编译。这可能会减慢编译速度。
C ++模板的另一个有趣的属性是它们可以应用于除类之外的其他东西 - 当它们存在时,它们的参数可以被自动检测到。例如:
template<typename T>
T min(const T &a, const T &b) {
return a > b ? b : a;
}
类型T将由使用该函数的上下文自动确定。
这些属性可以用来达到目的,牺牲你的理智。因为C ++模板是针对它所使用的每种类型重新编译的,并且编译器的实现始终可供编译器使用,所以C ++可以对模板进行非常积极的内联。除此之外,还可以自动检测函数中的模板值,并使用anonymous pseudo-functions在C ++中创建boost::lambda。因此,表达式如下:
_1 + _2 + _3
使用严重可怕的类型生成一个对象,该类型有一个运算符(),用于将其参数相加。
C ++模板系统还有很多其他的黑暗角落 - 它是一个非常强大的工具,但是可能很难思考,有时难以使用 - 特别是当它给你一个长达20页的错误消息时。 C#系统更简单 - 功能更强大,但更容易理解,更难滥用。
答案 1 :(得分:3)
http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88913.aspx
粗略地说,大部分差异与模板在编译时解析,并且泛型在运行时得到解决这一事实有关。
答案 2 :(得分:2)
Stack Overflow上的广泛答案:What are the differences between Generics in C# and Java... and Templates in C++?
答案 3 :(得分:1)
这个blog entry from Eric Gunnerson很好地涵盖了这个主题。
最大的直接差异是模板是编译时功能,而泛型是运行时功能。
答案 4 :(得分:0)