Templates

Template Instantiation

  • No automatic type conversion

    • Even with types that are convertible (e.g. int and float), multiple functions will still be generated for different types
  • Implicit template instantiation

    • func(a, b)
  • Explicit template instantiation

    • func<type>(a, b)
    • If a function does not have any argument, we must use explicit template instantiation

Stack vs Heap (p.11)

  • Stack variable defined later have a smaller address
  • Heap variable defined later have a larger address

|400

Template Specialization

  • No formal argument, and specify types of arguments
    • template <>

If we omit template <>, it is just a regular function

Class Template

template <typename T>
class ClassName
  • Must use explicit template Instantiation

  • Nontype parameters

    • Const variables

Pass Array as Reference

void func(int (&arr)[<size>]) {}

Separate Compilation

  • Template functions are only instantiated when it is used

  • Definition must be in the same file which calls it

  • Include .cpp files within .h, such that it is essentially “in the same file”

Operator Overloading

Rules

  • We can only overload existing operators except ., ::,?:, .*
  • Number of arguments cannot be changed
  • Associativity remains unchanged
  • Precedence remains unchanged

Operator Precedence/Associativity

PrecedenceOperatorAssociativity
2a++
a--
3++a
--a
5a * b
a / b
a % b
6a + b
a - b
7>>
<<

https://en.cppreference.com/w/cpp/language/operator_precedence

Global vs Member

  • User-defined operator functions can be called with its full name, e.g. operator+(), but built in operator cannot

  • Can be defined as both global or member function

// Global function
Interger operator+(const Intger& a, const Integer& b) {
    return Interger(a.getI() + b.getI());
}
 
// Member function
// Integer i3 = i1 + i2 will be compiled into 
// i1.operator+(i2)
Integer operator+(const Integer& a) {
    return Interger(i + a.i);
}
  • Type conversion only happens for parameters
    • For member operator function, 1.2 + vec which translates into 1.2.operator+(vec) does not work
    • For global operator function, all three cases (v + v, v + 1.2, 1.2 + v)work if there is a conversion constructor

Pre/Post-Increment

  • ++
    • Pre-increment
      • Vector& operator++();
    • Post-increment
      • Vector operator(int)