C# generics vs C++ templates - need a clarification about constraints

前端 未结 5 1121
萌比男神i
萌比男神i 2021-02-14 05:15

Duplicate

What are the differences between Generics in C# and Java… and Templates in C++?


Hi all,

I am experienced C++ p

5条回答
  •  萌比男神i
    2021-02-14 06:04

    C++ templates: The compiler checks whether the arguments satisfy the constraints set by the code. For example:

    template 
    class math_vector
    {
        T elements[dim];
    
        math_vector operator+ (const math_vector& other) const
        {
            math_vector result;
            for (unsigned int i = 0; i < dim; ++i)
                result.elements[i] = elements[i] + other.elements[i];
        }
    }
    
    struct employee
    {
        char name[100];
        int age;
        float salary;
    }
    
    math_vector int_vec; //legal
    math_vector float_vec; //legal
    math_vector employee_vec; //illegal, operator+ not defined for employee
    

    In this example, you could create a class, define operator+ for it and use it as a parameter for math_vector. Therefore, a template parameter is valid if and only if it satisfies the constraints defined by the template's code. This is very flexible, but results in long compilation times (whether a type satisfies the template's constraints must be checked every time the template is instantiated).

    C# generics: Instead of checking the validity of every particular instantiation, which results in longer compile times and is error prone, you declare explicitly that the generic's arguments must implement a particular interface (a set of methods, properties and operators). Inside the generic's code, you can't call any methods freely, but only those supported by that interface. Every time you instantiate a generic, the runtime doesn't have to check whether the argument satisfies a long set of constraints, but only whether it implements the specified interface. Of course, this is less flexible, but it's less error prone, too. Example:

    class SortedList where T : IComparable
    {
        void Add(T i) { /* ... */ }
    }
    
    class A : IComparable { /* ... */ }
    
    class B
    {
        int CompareTo(B b) { /* ... */ }
        bool Equals(B b) { /* ... */ }
    }
    
    SortedList sortedA; // legal
    SortedList sortedB; // illegal
    // B implements the methods and properties defined in IComparable,
    // however, B doesn't explicitly implement IComparable
    

提交回复
热议问题