Задание 3 (идивидуальное): использование метафункций из type_traits

Указания:

  • В этом задании необходимо использовать метафункции из стандартного заголовочного файла <type_traits>.
  • Для реализации вариантов шаблонов необходимо использовать принцип SFINAE.
  • В функции main() необходимо протестировать разработанные шаблоны с достаточным количеством тестов, покрывающих основные случаи использования этих шаблонов.

  1. Реализовать шаблонную функцию с шаблонным параметром-типом T и обычным параметром типа const T & и возвращающей указатель на const T. Если тип T является конструируемым по умолчанию, функция должна вернуть адрес статической локальной переменной, сконструированной по умолчанию. Иначе, если тип T является конструируемым от копии, функция должна вернуть адрес статической локальной переменной, сконструированной копией параметра функции. Иначе функция должна вернуть адрес своего параметра.

  2. Реализовать шаблонную функцию с шаблонным параметром-типом T и двумя обычными параметрами типов const T & и T &. Если тип T является типом POD, функция должна скопировать содержимое первого своего параметра во второй при помощи функции std::memcpy(). Иначе, если тип T является присваиваемым от копии, функция должна присвоить второму параметру значение первого. Иначе компиляция должна привести к пользовательскому сообщению об ошибке.

  3. Реализовать шаблонный класс с шаблонным параметром-типом T и полем i типа int («счётчик заполненности массива», изначально равный 0). Если тип T является массивом, определить внутри класса поле-массив типа T и метод add(), получающий ссылку на константное значение типа «элемент массива T» и присваивающий i-му элементу массива это значение, с последующим увеличением i. Иначе внутри класса нужно определить поле-массив из 100 элементов типа T и метод add(), получающий параметр типа const T & и выполняющий те же действия, что и в предыдущем случае.

  4. Реализовать шаблонный класс с шаблонным параметром-типом T. Если тип T является полиморфным классом или указателем на полиморфный класс, необходимо в шаблонном классе определить поле-список из указателей на такие классы. В деструкторе шаблонного класса необходимо обойти список и удалить каждый из объектов, указатель на который хранится в списке, при помощи операции delete. Иначе если тип T является конструируемым копией или перемещением, в шаблонном классе определить поле-вектор из таких типов. Иначе компиляция должна привести к пользовательскому сообщению об ошибке. В обоих правильных случаях в классе необходимо объявить метод add(), получающий либо указатель на полиморфный объект, либо тип const T & и добавляющий его копию в контейнер.

  5. Реализовать шаблонную функцию с двумя шаблонными параметрами-типами T1 и T2 и без обычных параметров. Если типы T1 и T2 одинаковые и конструируемые по умолчанию, функция должна вернуть указатель на объект типа T1, созданный в динамической памяти и проинициализированный конструктором по умолчанию. Иначе если типы T1 и T2 являются полиморфными классами, тип T2 конструируем по умолчанию и является производным от T1, то функция должна вернуть указатель на T1, ссылающийся на объект типа T2, созданный в динамической памяти при помощи конструктора по умолчанию. Иначе если выполняются те же условия кроме того, что, наоборот, тип T1 является производным от T2 и конструируем по умолчанию, тогда функция должна вернуть указатель на T2, ссылающийся на T1. Иначе компиляция должна привести к пользовательскому сообщению об ошибке.