Грабли, разбросанные в лабиринте шаблонов C++

четверг, 28 января 2010, Александр Решетник

Привет веем, доброго времени суток. Недавно наткнулся на Хабре на прикольную карту земель С++. Очень интересно ее исследовать с коллегами (сразу вспоминаются общие походы в Lineage).  

На карте есть лабиринт шаблонов. Увидел его и захотел рассказать о тех граблях, на которые приходилось наступать, бродя по этому лабиринту. Но сначала посмотрел, не было ли похожих историй до меня. Нашел очень классную статью "Трюки со специализацией шаблонов C++". Почерпнул из нее еще несколько идей и думаю, могу рассказать много интересного не только начинающим программистам.

Грабли №1. Дебагер Visual Studio не видит параметры данные из шаблона

Шаблоны в C++ кроме параметров типов поддерживают параметры обычного типа. Таким образом при создание объекта шаблонного класса есть возможность указать не только типы но и передать объекту данные. Для примера определим шаблонный класс для упаковки одномерного массива.

template

class Array
{
   public:
      T* M;
      Array() { M=new T[N];}
      ~Array(){delete [] M;}
      void Show();
};
 
template

void Array::Show()
{
      for(int i=0;i       {
            cout<       }
}

В параметры шаблона входит параметр N, который задает количество элементов массива. Во время работы дебагера этот параметр недоступен, хотя в коде он используется нормально.

Грабли №2. Можно создать локальную переменную, которая перекроет параметр

Добавим в функцию Show объявление переменной N.

template

void Array::Show()
{
      int tmp=N-1;
      int N=tmp;
      for(int i=0;i      {
            cout<      }
}
}

Таким образом, потерян последний элемент массива.

Грабли №3. Нельзя специализировать функцию для любых значений параметра N

Попробуем теперь специализировать функцию для типа float. Оказывается, компилятор требует указание конкретного значения параметров при специализации. И функция станет специальной только для этих параметров.

void Array::Show()
{
      for(int i=0;i      {
            printf("%.2f\n",M[i]);
      }
}

Если задать N =5, то при других значениях будет использоваться общая функция.

Как правильно обойти грабли №3 я так и не нашел. Кто знает, напишите.


Коллеги, если найдете ошибку (а я, к сожалению, не гуру — могу ошибаться) или у Вас есть критика, вопросы али дополнения к вышеизложенному — буду рад комментариям.


Ищите нас в интернетах!

Комментарии

Свежие вакансии