将C++移植到C# - 模板

Iai*_*oat 5 .net c# c++ templates porting

我正在将C++应用程序移植到C#,并且已经跨模板运行.我已经阅读了一些这些,我知道有些模板类似于.Net泛型.我读了这个案例的SO答案,很好地总结了它.

但是,c ++模板的一些用法似乎与泛型没有直接关系.在以下维基百科的模板元编程文章示例中,模板似乎接受一个值,而不是一个类型.我不太确定如何移植到C#?

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}
Run Code Online (Sandbox Code Playgroud)

显然,对于这个例子,我可以这样做:

public int Factorial(int N){
    if(N == 0) return 1;
    return Factorial(N - 1);
}
Run Code Online (Sandbox Code Playgroud)

但在我看来,这似乎是对函数的重构,而不是语义类似代码的端口.

And*_*tan 5

不幸的是.Net泛型只能接受类型.C++模板采用编译器认为是常量表达式的其他值,因为它们实际上只是扩展为更多代码的宏.

这意味着您将代码转换为方法调用的想法是最好的选择.您可以使方法调用返回一个带有.Value属性的类型(按照您的示例),从而使移植的代码保持与模板类似:

return Factorial(N-1).Value;
Run Code Online (Sandbox Code Playgroud)


Kon*_*lph 5

在下面的示例中......模板似乎接受一个值,而不是一个类型.

这不是你最大的问题.事实上,理论上可以通过使用基于嵌套泛型类型的Church数字或Peano表示在C#中解决.1

但是,您的问题是C#不允许模板专门化.模板专门负责在你的例子定义了阶乘的0IS 1,而不是相同的所有其他号码.C#不允许这样做.

因此,无法在递归模板(通用)定义中指定基本案例,因此无法递归.C#泛型不是图灵完整的,而C++模板是.


1像这样:

class Zero { }

class Successor<T> : Zero where T : Zero { }

// one:
Successor<Zero>
// two:
Successor<Successor<Zero>>
// etc.
Run Code Online (Sandbox Code Playgroud)

对这些数字实施操作留给读者练习.