Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Porting C++ to C# - templates

I'm porting a C++ application to C#, and have run across templates. I've read up a little on these, and I understand that some templates are akin to .Net generics. I read the SO answer to this case which nicely summed it up.

However, some uses of c++ templating don't seem to be directly related to generics. In the below example from Wikipedia's Template metaprogramming article the template seems to accept a value, rather than a type. I'm not quite sure how this would be ported to 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
}

Clearly for this example I could do:

public int Factorial(int N){
    if(N == 0) return 1;
    return Factorial(N - 1);
}

but this seems to me to be a refactoring to a function, rather than a port to semantically similar code.

like image 603
Iain Sproat Avatar asked Jan 19 '11 13:01

Iain Sproat


People also ask

Is C or C faster?

Performance-based on Nature Of Language C++ language is an object-oriented programming language, and it supports some important features like Polymorphism, Abstract Data Types, Encapsulation, etc. Since it supports object-orientation, speed is faster compared to the C language.

Can you convert CPP to C?

It is possible to implement all of the features of ISO Standard C++ by translation to C, and except for exception handling, it typically results in object code with efficiency comparable to that of the code generated by a conventional C++ compiler.


2 Answers

Unfortunately .Net generics can only accept types. C++ Templates take other values that are considered constant expressions by the compiler, because they are effectively just macros that expand to more code.

This means that your idea of turning the code into a method call is the best bet. You could make the method call return a type with a .Value Property (following your example) thus keeping the ported code similar to the template:

return Factorial(N-1).Value;
like image 157
Andras Zoltan Avatar answered Oct 17 '22 23:10

Andras Zoltan


In the below example … the template seems to accept a value, rather than a type.

This isn’t your biggest problem. In fact, this could theoretically be solved in C# by using a Church numeral or Peano representation relying on nested generic types.1

However, your problem is that C# doesn’t allow template specialization. Template specialization is responsible in your example for defining that the factorial of 0 is 1, rather than the same as for all other numbers. C# doesn’t allow doing that.

So there is no way to specify a base case in a recursive template (generic) definition and hence no recursion. C# generics aren’t Turing complete, whereas C++ templates are.


1 Something like this:

class Zero { }

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

// one:
Successor<Zero>
// two:
Successor<Successor<Zero>>
// etc.

Implementing operations on these numbers is left as an exercise to the reader.

like image 5
Konrad Rudolph Avatar answered Oct 17 '22 23:10

Konrad Rudolph