难以理解的语法,从vc ++到c#

roa*_*cel 4 c# syntax visual-c++

我有以下代码,这对于理解我正在从可视化c ++转换为c#的类非常重要

typedef Rect<double, 2> Rect2;
Run Code Online (Sandbox Code Playgroud)

我根本无法理解它是什么意思.我已经明白vc ++使用'stl'或'std'和'vector'类,类似于c#list或arraylist,但语法完全不适合我.

顺便说一句,Rect定义是这样写的

template<class Real, int Dim>
class Rect {
Run Code Online (Sandbox Code Playgroud)

Rect是其中一个vc ++项目文件中的一个类,但我无法理解这个typedef的重点.这是200多行,所以这是宣言的开始

template<class Real, int Dim>
class Rect {
public:

typedef Vector<Real, Dim> Vec;
typedef Rect<Real, Dim> Self;
typedef _RectPrivate::RectOp<Dim> RO;

Rect() : empty(true) {}
Rect(const Vec &vec) : empty(false), lo(vec), hi(vec) {}
Rect(const Vec &inLo, const Vec &inHi) : lo(inLo), hi(inHi) { markEmpty(); }
Rect(const Rect &inRect) : empty(inRect.empty), lo(inRect.lo), hi(inRect.hi) {}
template<class R> Rect(const Rect<R, Dim> &inRect) : empty(inRect.empty), lo(inRect.lo), hi(inRect.hi) {}
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏.

Eri*_*ert 7

根据您对其他答案的评论,您面临的问题是您不了解C++模板是什么.它们实际上与C#泛型完全不同.它们在概念上类似,在语法上相似,但它们的实际实现是非常不同的.

在C++中考虑模板的最简单方法是作为"搜索和替换"机制.当你看到

typedef Rect<double, 2> Rect2;
Run Code Online (Sandbox Code Playgroud)

这意味着要找到带有两个模板参数的Rect的模板类.这里是:

template<class Real, int Dim>
class Rect {
Run Code Online (Sandbox Code Playgroud)

好的,所以"double"对应"class Real","2"对应"int Dim".果然,double是一个类型,2是一个int,所以它可以正常工作.现在浏览模板类,用"double"和"Dim"替换所有"Real"实例.结果是:

typedef /* now we start replacing double for Real and 2 for Dim */ 
class Rect {
public:
typedef Vector<double, double> Vec;
typedef Rect<double, 2> Self;
typedef _RectPrivate::RectOp<2> RO;
Rect() : empty(true) {}
Rect(const Vec &vec) : empty(false), lo(vec), hi(vec) {}
...
} Rect2;
Run Code Online (Sandbox Code Playgroud)

请注意,模板本身的搜索和替换结果都定义并使用了更多模板,这些模板本身必须进行搜索和替换才能构建它们.我们在Vector模板上进行搜索和替换,依此类推.

"typedef"仅仅意味着"我说的Rect2意思是Rect<double, 2>".你可以说在C#中的方式相同

using MyStringList = System.Collections.Generic.List<string>;
Run Code Online (Sandbox Code Playgroud)

C#泛型和C++模板之间存在许多差异.这里明显的区别是C#泛型只能用类型进行参数化,而不能像在此模板中那样使用进行参数化.另一个区别是C++模板在编译时完全构造,并且只需要在程序中给出的实际参数合法构造.而C#泛型必须可以使用满足所述约束的任何参数构造,并且新代码生成直到运行时才会发生.

  • @lukas:在运行时使用泛型会有性能和空间损失,因为使用泛型的*first*time必须在运行时进行代码生成.但是,每个appdomain每个构造只发生一次codegen.此外,使用类型参数的引用类型构造的两个构造仅产生惩罚*一次*.因此,当您创建第一个`List <string>`时,您将免费获得`List <任何其他引用类型>`.此外,通过使用由值类型构造的泛型,您可以获得第一次调用jit成本但消除每次调用的装箱成本. (3认同)