С++ для начинающих




Объекты-функции


Наша функция min() дает хороший пример как возможностей, так и ограничений механизма шаблонов:

template <typename Type>

const Type&

min( const Type *p, int size )

{

   Type minval = p[ 0 ];

   for ( int ix = 1; ix < size; ++ix )

      if ( p[ ix ] < minval )

         minval = p[ ix ];

      return minval;

}

Достоинство этого механизма – возможность определить единственный шаблон min(), который конкретизируется для бесконечного множества типов. Ограничение же заключается в том, что даже при такой конкретизации min() будет работать не со всеми.

Это ограничение вызвано использованием оператора “меньше”: в некоторых случаях базовый тип его не поддерживает. Так, класс изображения Image может и не предоставлять реализации такого оператора, но мы об этом не знаем и пытаемся найти минимальный кадр анимации в данном массиве изображений. Однако попытка конкретизировать min() для такого массива приведет к ошибке компиляции:

error: invalid types applied to the < operator: Image < Image

(ошибка: оператор < применен к некорректным типам: Image < Image)

Возможна и другая ситуация: оператор “меньше” существует, но имеет неподходящую семантику. Например, если мы хотим найти наименьшую строку, но при этом принимать во внимание только буквы, не учитывая регистр, то такой реализованный в классе оператор не даст нужного результата.

Традиционное решение состоит в том, чтобы параметризовать оператор сравнения. В данном случае это можно сделать, объявив указатель на функцию, принимающую два аргумента и возвращающую значение типа bool:

template < typename Type,

           bool (*Comp)(const Type&, const Type&)>

const Type&

min( const Type *p, int size, Comp comp )

{

   Type minval = p[ 0 ];

   for ( int ix = 1; ix < size; ++ix )

      if ( Comp( p[ ix ] < minval ))

         minval = p[ ix ];

      return minval;

}

Такое решение вместе с нашей первой реализацией на основе встроенного оператора “меньше” обеспечивает универсальную поддержку для любого типа, включая и класс Image, если только мы придумаем подходящую семантику для сравнения двух изображений. Основной недостаток указателя на функцию связан с низкой эффективностью, так как косвенный вызов не дает воспользоваться преимуществами встроенных функций.




Содержание  Назад  Вперед