Tuesday, March 09, 2004

Re: C++ Generics

could you give some places where templates, both class and function would be used. other than containers.

Containers are the most popular candidates because they are an abstraction that, by nature, are generic. I mean when you talk about an Array or List or Dictionary, you don't think about it in terms of a specific type. So when you think of templates etc... you immediately think of collections.

But there are many other places where genericity plays a role. For example, there is a class called auto_ptr in STL. This is a utility class that helps with memory management. In C++, when you create an object on the heap with "new", it is your responsibility to free it with "delete". But there are times when this fails to happen.

Consider this...

function foo()
{
    MyClass* pBar = new MyClass;

    DoSomethingThatCausesAnExceptionToBeThrown();

    delete pBar;
}


In this case, you allocate/initialize on the heap. Then you jump to another function. That function throws an exception and the stack unwinds both functions. You never get to "delete pBar". Memory leak. You can use auto_ptr to help you out. auto_ptr takes a pointer (to an object on the heap). When it goes out of scope, it calls "delete" on the pointer you pass it...

function foo()
{
    auto_ptr<MyClass> bar( new MyClass );

    DoSomethingThatCausesAnExceptionToBeThrown();
}


Here, bar is just a local variable created on the stack. When the function ends or the stack unwinds (because of an exception), bar's destructor is called, which in turn calls delete on the pointer passed to it.

auto_ptr is a generic class. It can hold on to a pointer of ANY type you pass it.

Similar to auto_ptr is pair. This is a class that holds on to a tuple. It is generic in that it can hold on to two objects of ANY type...

template <typename T1, typenameT2>
class pair
{
    private:
        T1 first;
        T2 second;

    public:
        pair( T1 f, T2 s ) : first( f ), second( s ) { }

...
}


should the 'size_t n' variable you created in the class template example be 'int n'??

size_t is an unsigned type defined in one of the standard C header files... dunno which one exactly. This is basically defined for any positive range like # of elements in a collection. It really is just a typedef for an unsigned integral.

how is the generics implementation in .net?

As I said before, in C++ everything happens at compile time. In C#, it's both compile and runtime. When you create a template class in C++, the compiler removes the actual template class and replaces it with classes of a specific type(s). In C#, the compiler emits IL code and metadata for the actual template. At runtime, the JITer will create actual classes of specific types as it is encountered.

In C# there is less freedom in the types you can use in templates. When you create a template, you define constraints on the types you can use the template with...

public class MyClass<T> where T : IComparable
{
    // Do stuff with T on IComparable methods
}


The constraint here is that all types with which you instantiate MyClass have to implement IComparable. The compiler will ensure that it does. So at runtime you don't have to worry about checking whether a type defines a specific method or not.

i am basically trying to gear up for java 1.5.

I read that Java generics are being implemented such that no changes to the JVM will be required. This is a good benefit. But apparently, this means that it won't provide "true" template functionality because you can't modify the bytecode. As in, it's going to be syntactic sugar for the programmer. The compiler will be using Object for the type and inject casts in the bytecode. Also, when using reflection on a generic class, you won't be able to tell what type it was instantiated with. Have you heard anything about this?

No comments: