C#泛型与C++模板进行了比较

Bja*_*sen 10 c# c++ generics comparison templates

可能重复:
C#和Java中的泛型与C++中的模板有什么区别?

C#泛型与C++模板之间有什么区别?我知道他们并没有解决完全相同的问题,那么两者的优点和缺点是什么?

bdo*_*lan 21

您可以将C++模板视为一种伪装成泛型系统的解释型函数式编程语言.如果这不吓到你,那应该:)

C#泛型非常有限; 您可以参数化一个或多个类型的类,并在方法中使用这些类型.因此,从MSDN中获取示例,您可以:

public class Stack<T>
{
   T[] m_Items; 
   public void Push(T item)
   {...}
   public T Pop()
   {...}
}
Run Code Online (Sandbox Code Playgroud)

现在你可以声明一个Stack<int>Stack<SomeObject>它将安全地存储该类型的对象(即,不担心SomeOtherObject错误地输入).

在内部,.NET运行时将把它专门化为基本类型(如int)的变体,以及对象类型的变体.例如,这允许表示Stack<byte>远小于Stack<SomeObject>例如的表示.

C++模板允许类似的用途:

template<typename T>
class Stack
{
    T *m_Items;
    public void Push(const T &item)
    {...}
    public T Pop()
    {...}
};
Run Code Online (Sandbox Code Playgroud)

乍一看这看起来很相似,但有一些重要的区别.首先,对于每个基本类型而不是一个变体,而不是所有对象类型的变体,对于它实例化的每种类型都有一个变体.那可以是很多类型!

下一个主要区别是(在大多数C++编译器上)它将在它使用的每个转换单元中编译.这可能会减慢编译速度.

C++模板的另一个有趣的属性是它们可以应用于除类之外的其他东西 - 当它们存在时,它们的参数可以被自动检测到.例如:

template<typename T>
T min(const T &a, const T &b) {
  return a > b ? b : a;
}
Run Code Online (Sandbox Code Playgroud)

类型T将由使用该函数的上下文自动确定.

这些属性可以用于良好的目的,而牺牲你的理智.因为C++模板是针对它所使用的每种类型重新编译的,并且编译器的实现始终可供编译器使用,所以C++可以对模板进行非常积极的内联.除此之外,还可以自动检测函数中的模板值,并且可以使用boost :: lambda在C++中创建匿名伪函数.因此,表达式如下:

_1 + _2 + _3

生成一个具有严重可怕类型的对象,该对象具有一个运算符(),该运算符将其参数相加.

C++模板系统还有很多其他的黑暗角落 - 它是一个非常强大的工具,但是可能很难思考,有时候很难使用 - 特别是当它给你一个长达20页的错误消息时.C#系统更简单 - 功能更强大,但更容易理解,更难以滥用.

  • *C++ 模板的另一个有趣的属性是它们可以应用于类以外的事物* - 这与 C# 允许我们在函数中定义泛型相同吗(例如 `T SomeFunc&lt;T&gt;(T input){...} `)? (2认同)

Pau*_*ier 5

http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88913.aspx

粗略地说,大部分差异与模板在编译时解析,而泛型在运行时解析这一事实有关。

  • 实际上,尽管泛型可以在运行时实例化(通过反射,就像其他任何东西一样),但很多事情都是在编译时解决的。例如,JIT 生成“List&lt;int&gt;”的特定实现,而不是使用与“List&lt;object&gt;”等效的常见类型擦除版本(这是它与 Java 不同的一种方式)。 (2认同)