Грабли, разбросанные в лабиринте шаблонов C++
Привет веем, доброго времени суток. Недавно наткнулся на Хабре на прикольную карту земель С++. Очень интересно ее исследовать с коллегами (сразу вспоминаются общие походы в 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
{
for(int i=0;i
cout<
}
В параметры шаблона входит параметр N, который задает количество элементов массива. Во время работы дебагера этот параметр недоступен, хотя в коде он используется нормально.
Грабли №2. Можно создать локальную переменную, которая перекроет параметр
Добавим в функцию Show объявление переменной N.
template
void Array
{
int tmp=N-1;
int N=tmp;
for(int i=0;i
cout<
}
}
Таким образом, потерян последний элемент массива.
Грабли №3. Нельзя специализировать функцию для любых значений параметра N
Попробуем теперь специализировать функцию для типа float. Оказывается, компилятор требует указание конкретного значения параметров при специализации. И функция станет специальной только для этих параметров.
void Array
{
for(int i=0;i
printf("%.2f\n",M[i]);
}
}
Если задать N =5, то при других значениях будет использоваться общая функция.
Как правильно обойти грабли №3 я так и не нашел. Кто знает, напишите.
Коллеги, если найдете ошибку (а я, к сожалению, не гуру — могу ошибаться) или у Вас есть критика, вопросы али дополнения к вышеизложенному — буду рад комментариям.