Templates

W
Document Sample
scope of work template
							Templates

Kenneth Chiu
    More Unsigned Questions
• What does this print?
  – size_t a = 3, b = 5;
    size_t u = 10;
    long long ll = 10;
    u += a - b;
    ll += a - b;
    printf("%u, %lld\n",
           (unsigned int) u, ll);
         Pointers to Members
• “All problems in computer science can be
  solved with another level of indirection”
                         – Butler Lampson
  – class A {
        int f(int); int g(int); };
   A a;
   foo(&a, ?);
• Pointers to members
  – void foo(A *a, int (A::*fp)(int));
    foo(&a, &A::f);
• #include <stdio.h>
  class A {
     public:
        int f(int) { printf("Called A::f().\n"); }
        int g(int) { printf("Called A::g().\n"); }
  };
  void f(A *a, int (A::*ptm)(int)) {
     (a->*ptm)(0);
  }
  int main() {
     A a;
     f(&a, &A::g);
     f(&a, &A::f);
  }
                   Introduction
• A template is just that, a template or “pattern”.
• Essentially a macro on steroids.
• How is a template different from normal source
  code?
   – void foo() {…}
      template <typename T>
      void foo1() {…}
   – Template definitions are not really “compiled”.
      • Just cause things to be remembered.
• Some of these slides might be hard to
  understand, so please interrupt if I go to fast.
      Templates Are Macros
• Where do you put templates, header files
  or implementation files?
  – Every use must be preceded in the same
    translation unit by its definition.
  – Private template could be in an
    implementation file.
Templates and Classes as Models
• Both are “models”.
  – Classes are models for objects. An object:
     •   Has source code (member functions).
     •   Has data (member variables).
     •   But source code never differs.
     •   Data layout never differs. Only the values differ.
  – Templates go back one step. They are models for
    classes. You first instantiate a template to fix a
    particular source code and data layout.
     • The source code can differ.
     • The data layout can differ.
How Do Templates Get Instantiated?
• Implicitly
   –  template <typename T>
      void foo(T) {…}
      foo(1);
   – What happens if later on in this translation unit you have:
       • foo(4);
       • foo(3.14);
   – What happens if later on in a different translation unit you have:
       • foo(5);
       • What really happens?
• Explicitly
   – template void foo<int>(int);
   – What happens if later on in this translation unit you have:
       • template void foo<int>(int);
       • foo(4);
How Do Templates Get Instantiated?
• What happens if a template is implicitly
  instantiated in one translation unit, and explicitly
  in another?
• What if it is first implicitly instantiated, then
  explicitly instantiated in the same translation
  unit?
• Trying to remember all the rules will drive you
  crazy.
   – Instead understand the purpose of instantiation, and
     understand the underlying techniques.
   – This will help you immensely when trying to track
     down errors.
           Function Templates
• Defining min():
   – #define min(a, b) ((a) < (b)) ? (a) : (b))
   – Any problems with this?
• Basic syntax
   – template <typename T>
      T min(T a, T b) { return a < b ? a : b; }
   – What changes would you make to the above?
      • What happens when called with ++?
• g++ standard library definition
   – template<typename _Tp>
      inline const _Tp&
      min(const _Tp& __a, const _Tp& __b) {
           if (__b < __a) return __b; return __a; }
   – Why the underscores?
      Non-Type Parameters
• Why might this be useful?
  – template <typename T, int N>
     void sort(T (&a)[N]) {
         T save[N];
         if (i < N) {…}
     }
              Specialization
• Consider:
  – template <typename T>
     T min(T a, T b) {
     return (a < b) ? a : b; }
• What happens when you call?
  – min(“a”, “b”)
• Define
  – template <>
     const char *
     min(const char *a, const char *b) {
        return (strcmp(a, b) < 0) ? a : b; }
             Typenames
• Consider
  – template <typename T>
     void foo(T) {
        T::name * p; }
• What is T::name?
• Use typename keyword
  – template <typename T>
     void foo(T) {
        typename T::name * p; }
 Template Mixed with Nontemplate
• Is this valid?
   – template <typename T>
      T sum(T, int);
      double sum(double, double);
• Which one gets called?
   – sum(3.14, 3.14);
   – sum(3.14, 1);
   – sum(1, 3.14);
• Know what you don’t know.
   – Known unknowns are okay, unknown unknowns are
     bad. (Especially if your initials are D.R.)
 Template Argument Deduction
• Consider
  – template <typename T>
     T min(T a, T b) {
     return a < b ? a : b; }
• What happens when you call?
  – min(1, 3.14)
• Explicit arguments
  – min<double>(1, 3.14)
             Class Templates
• Consider
  – template <typename T, int N>
     class Array {
         T a[N];
         T operator[](int i) {
             return a[i]; }
     };
• How do you use this?
  – Array<int, 10> a;
• How might you improve this?
  – Range check, Lvalue, const
            Specializations
• Specialize member functions individually:
  – template <>
    double A<double>::foo() {…}
• Where do these go, header or program
  text?
  – Must place a declaration before point of
    instantiation.
• Specialize whole class template
  – template <typename T> class A {…};
     template <> class A<double> {…};
• Where do these go?
• Traits
  – template <> class Traits<Alice> {
        static const Color
            hair_color = BLACK;
        static const Color
            eye_color = BLACK;
        static const int
            weight = 135;
    };
    template <> class Traits<Bob> {…};
    color = Traits<Bob>::hair_color;
     Partial Specialization
• template <typename T1, int N>
  class A {…};
  template <typename T1>
  class A<T1, 2> {…};
• template <typename T1, int N>
  class A<   T1, N < 2    > {…};
        Member Templates
• A member function can be a template:
  – class A {
            template <typename T>
            T foo(T);
     };
  – For example, suppose you are writing an XML
    serializer:
    • class Serializer {
           template <typename T>
           void emit(T v) const {
               sprintf(p, ???, v);

						
Related docs