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)
但在我看来,这似乎是对函数的重构,而不是语义类似代码的端口.
不幸的是.Net泛型只能接受类型.C++模板采用编译器认为是常量表达式的其他值,因为它们实际上只是扩展为更多代码的宏.
这意味着您将代码转换为方法调用的想法是最好的选择.您可以使方法调用返回一个带有.Value属性的类型(按照您的示例),从而使移植的代码保持与模板类似:
return Factorial(N-1).Value;
Run Code Online (Sandbox Code Playgroud)
在下面的示例中......模板似乎接受一个值,而不是一个类型.
这不是你最大的问题.事实上,理论上可以通过使用基于嵌套泛型类型的Church数字或Peano表示在C#中解决.1
但是,您的问题是C#不允许模板专门化.模板专门负责在你的例子定义了阶乘的0
IS 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)
对这些数字实施操作留给读者练习.