Работает как очистка памяти и все остальные шаблоны, без указания размера и типа, но правильно ли реализованы сами шаблоны?
namespace msafe
{
// используется исключительно для освобождения COM объектов
template <class T>
void srel(T& t)
{
if (t)
{
t->Release();
t = nullptr;
}
}
// используется для удаления объектов классов, созданных пользователем/разработчиком
template <class T>
void sdel(T& t)
{
if (t)
{
delete t;
t = nullptr;
}
}
// используется для упрощения очистки памяти под структуры
template <typename T>
void* setz(T& t)
{
return memset(&t, 0, sizeof(T));
}
// используется для удаления массивов из памяти
template <class T>
void sdel_arr(T& t)
{
if (t)
{
delete[] t;
t = nullptr;
}
}
}
Местами надо добавить *.
Например,
template <class T>
void srel(T*& t)
{
if (t)
{
t->Release();
t = nullptr;
}
}
Вообще, Ваш код чреват ошибками выполнения. Условие в if, соответствие форм new и delete, гарантии наличия ф-ии члена Release(). Что, если, к примеру, пользователь вызовет функцию sdel() для С-массива или вообще для неуказательного типа? Будет явно неприятно.
Лучше объявляйте деструктор и в нем пишите, что Вы хотите дополнительно сделать при удалении. А если хотите работать с указателями, то используйте прокси-классы, например, std::shared_ptr, std::unique_ptr и т.п. Они позволяют при создании объекта указать пользовательский удалитель, например, некую функцию или лямбду. Правда, этого нельзя сделать, если Вы будете использовать make-функции. Также интеллектуальные указатели не работают с типами массива, поскольку у них используется инструкция delete без []. Но и это не проблема - STL изобилует контейнерами на любой вкус.
При выводе параметра шаблона игнорируется его константность и ссылочность, но при этом не игнорируется указатель
int x;
const int& crx = x;
int* px = &x;
template<class T>
void f(T t) { /* ... */ }
f(x); // T = int, в функцию передается копия x по значению
f(crx); // T = int, модификаторы const и & игнорируются
f(px); // T = int*, указатель не игнорируется
чтобы аргументу функции указать const и & для типа, необходимо прописать их явно
template<class T>
void f(const T& t) { /* ... */ }
f(x); // T = const int&, в функцию передается копия x по значению
f(crx); // T = int, модификаторы const и & на этапе вывода типа для T игнорируются, но добавляются для типа аргумента, т. к. они указаны
можно так же передавать и указатель (лучше так и делать, это показывает явное намерение, что шаблонная функция ожидает в качестве параметра указатель)
template<class T>
void f(T* t) { /* ... */ }
f(x); // ошибка при компиляции, функция принимает только указатели
f(px); // T = int*
f(&px); // T = int**
со всем этим хочу так же выделить один момент на счет отбрасывания const
template<class T>
void f(T t) { /* ... */ }
const int* const cpcx = *x; // константный указатель на константный int
f(x); // T = const int*, отбросился const, который отвечает за константность указателя, но остался тот, который отвечает за константность того, что лежит по этому указателю
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости