8.4.1 Простой шаблон типа для глобальной функции.

   


Назад  |  Вперёд

Начнем с простейшего шаблона для sort():

           template<class T> void sort(Vector<T>&);

           void f(Vector<int>& vi,
                  Vector<String>& vc,
                  Vector<int>& vi2,
                  Vector<char*>& vs)
           {
             sort(vi);      // sort(Vector<int>& v);
             sort(vc);      // sort(Vector<String>& v);
             sort(vi2);     // sort(Vector<int>& v);
             sort(vs);      // sort(Vector<char*>& v);
           }

Какая именно функция sort() будет вызываться определяется фактическим параметром. Программист дает определение шаблона типа для функции, а задача системы программирования обеспечить создание правильных вариантов функции по шаблону и вызов соответствующего варианта. Например, простой шаблон с алгоритмом пузырьковой сортировки можно определить так:

           template<class T> void sort(Vector<T>& v)
           /*
              Сортировка элементов в порядке возрастания
              Используется сортировка по методу пузырька
           */
           {
             unsigned n = v.size();

             for (int i=0; i<n-1; i++)
                 for (int j=n-1; i<j; j--)
                     if (v[j] < v[j-1]) {  // меняем местами v[j] и v[j-1]
                        T temp = v[j];
                        v[j] = v[j-1];
                        v[j-1] = temp;
                     }
           }

Советуем сравнить это определение с функцией сортировки с тем же алгоритмом из $$4.6.9. Существенное отличие этого варианта в том, что вся необходимая информация передается в единственном параметре v. Поскольку тип сортируемых элементов известен (из типа фактического параметра, можно непосредственно сравнивать элементы, а не передавать указатель на производящую сравнение функцию. Кроме того, нет нужды возиться с операцией sizeof. Такое решение кажется более красивым и к тому же оно более эффективно, чем обычное. Все же оно сталкивается с трудностью. Для некоторых типов операция < не определена, а для других, например char*, ее определение противоречит тому, что требуется в приведенном определении шаблонной функции. (Действительно, нам нужно сравнивать не указатели на строки, а сами строки). В первом случае попытка создать вариант sort() для таких типов закончится неудачей (на что и следует надеяться) , а во втором появиться функция, производящая неожиданный результат.

Чтобы правильно сортировать вектор из элементов char* мы можем просто задать самостоятельно подходящее определение функции sort(Vector<char*>&):

           void sort(Vector<char*>& v)
           {
             unsigned n = v.size();

             for (int i=0; i<n-1; i++)
                for ( int j=n-1; i<j; j--)
                    if (strcmp(v[j],v[j-1])<0) {
                    // меняем местами v[j] и v[j-1]
                       char* temp = v[j];
                       v[j] = v[j-1];
                       v[j-1] = temp;
                    }
           }

Поскольку для векторов из указателей на строки пользователь дал свое особое определение функции sort(), оно и будет использоваться, а создавать для нее определение по шаблону с параметром типа Vector<char*>& не нужно. Возможность дать для особо важных или "необычных" типов свое определение шаблонной функции дает ценное качество гибкости в программировании и может быть важным средством доведения программы до оптимальных характеристик.


Назад  |  Вперёд


OtDiatlovaOU
К началу книги

Оформление и дизайн книги OtDiatlovaOU.
Вся книга, архив.