псевдоним template класса с незаданным параметром?
От: Василий Зверев Россия  
Дата: 03.12.08 15:41
Оценка:
Не уверен, что удачно сформулировал заголовок, но задача у меня следующая.
Я пытаюсь создать свой auto_ptr.
Сделал такой шаблон класса:
// auto pointer/auto handle class.
// automatically destroys pointer/closes handle when object destroyed.
template<typename PTR, void DESTROY_FUNC(PTR)>
class my_auto_ptr
{
// реализация
};

// короткие названия для часто используемых типов
typedef my_auto_ptr<HANDLE, destroy_handle> auto_handle;

// destroy_handle() в данном примере определена отдельно:
inline void destroy_handle(HANDLE ptr)
{
    CloseHandle(ptr);
}

В моём проекте/подпроектах память может выделяться двумя разными способами:
либо malloc() из стандартной библиотеки,
либо HeapAlloc(GetProcessHeap(), ...) из Win32 API.

Я создал соответственно две функции для освобождения памяти:
template<typename PTR>
inline void destroy_heap_ptr(PTR ptr)
{
    HeapFree(GetProcessHeap(), 0, ptr);
}

template<typename PTR>
inline void destroy_free_ptr(PTR ptr)
{
    free(ptr);
}

Создать my_auto_ptr теперь можно например так:
my_auto_ptr<char*, destroy_free_ptr> pString = malloc(1024);

Я же хочу задать короткие имена, что-нибудь в таком роде:
// здесь компилятор заслуженно ругается на PTR -- дескать не знаю, что это.
typedef my_auto_ptr<PTR, destroy_free_ptr> auto_free_ptr<PTR>;
typedef my_auto_ptr<PTR, destroy_heap_ptr> auto_heap_ptr<PTR>;

Как это можно сделать?
Re: псевдоним template класса с незаданным параметром?
От: Were  
Дата: 03.12.08 16:16
Оценка: 9 (2)
Здравствуйте, Василий Зверев, Вы писали:

ВЗ>Я же хочу задать короткие имена, что-нибудь в таком роде:

ВЗ>
ВЗ>// здесь компилятор заслуженно ругается на PTR -- дескать не знаю, что это.
ВЗ>typedef my_auto_ptr<PTR, destroy_free_ptr> auto_free_ptr<PTR>;
ВЗ>typedef my_auto_ptr<PTR, destroy_heap_ptr> auto_heap_ptr<PTR>;
ВЗ>

ВЗ>Как это можно сделать?


template < typename PTR >
    struct auto_free_ptr
{
    typedef my_auto_ptr<PTR, destroy_free_ptr> type;
};

auto_free_ptr< char* >::type pString = malloc(1024);
Re: псевдоним template класса с незаданным параметром?
От: Alexander G Украина  
Дата: 03.12.08 16:33
Оценка:
Здравствуйте, Василий Зверев, Вы писали:

ВЗ>Я же хочу задать короткие имена, что-нибудь в таком роде:

ВЗ>
ВЗ>// здесь компилятор заслуженно ругается на PTR -- дескать не знаю, что это.
ВЗ>typedef my_auto_ptr<PTR, destroy_free_ptr> auto_free_ptr<PTR>;
ВЗ>typedef my_auto_ptr<PTR, destroy_heap_ptr> auto_heap_ptr<PTR>;
ВЗ>

ВЗ>Как это можно сделать?

Шаблонные typedefы будут в С++, а пока — может подойти такое:
template<typename PTR>
struct auto_heap_ptr : my_auto_ptr<PTR, destroy_heap_ptr> {};
Русский военный корабль идёт ко дну!
Re[2]: псевдоним template класса с незаданным параметром?
От: Were  
Дата: 03.12.08 17:09
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, Василий Зверев, Вы писали:


ВЗ>>Я же хочу задать короткие имена, что-нибудь в таком роде:

ВЗ>>
ВЗ>>// здесь компилятор заслуженно ругается на PTR -- дескать не знаю, что это.
ВЗ>>typedef my_auto_ptr<PTR, destroy_free_ptr> auto_free_ptr<PTR>;
ВЗ>>typedef my_auto_ptr<PTR, destroy_heap_ptr> auto_heap_ptr<PTR>;
ВЗ>>

ВЗ>>Как это можно сделать?

AG>Шаблонные typedefы будут в С++, а пока — может подойти такое:

AG>
AG>template<typename PTR>
AG>struct auto_heap_ptr : my_auto_ptr<PTR, destroy_heap_ptr> {};
AG>


Врядли. У умного указателя наверняка имеются кастомные конструкторы и операторы присваивания.
Re[3]: псевдоним template класса с незаданным параметром?
От: Alexander G Украина  
Дата: 03.12.08 17:54
Оценка:
Здравствуйте, Were, Вы писали:

W>Врядли. У умного указателя наверняка имеются кастомные конструкторы и операторы присваивания.


Конструкторы, кроме копирования — зафорвардить вручную, оператор = сам сгенерится.

Конечно, для смартпоинтера это плохой вариант, но луше не знаю
Русский военный корабль идёт ко дну!
Re[4]: псевдоним template класса с незаданным параметром?
От: Erop Россия  
Дата: 03.12.08 18:33
Оценка:
Здравствуйте, Alexander G, Вы писали:

W>>Врядли. У умного указателя наверняка имеются кастомные конструкторы и операторы присваивания.

AG>Конструкторы, кроме копирования — зафорвардить вручную, оператор = сам сгенерится.
AG>Конечно, для смартпоинтера это плохой вариант, но луше не знаю

Ну можно, например, поступить так, как тут уже советовали, но постараться обойтись без слова type.
Так, чтобы писалось как-то так:
auto_free<T>::ptr, auto_heap<T>::ptr
а можно ещё макросы завести AUTO_FREE_PTR(PTR) и AUTO_HEAP_PTR(PTR)

только как-то не понятно на кой это всё надо? Может быть каким-то уже готовым смартпоинтером стоит попользоваться? Там много прикольного уже люди напридумывали, вообще-то...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: псевдоним template класса с незаданным параметром?
От: byleas  
Дата: 04.12.08 00:09
Оценка: 3 (1)
Здравствуйте, Were, Вы писали:

Угу, Templated typedef "для бедных", то есть, в отсутствие этой фичи из нового стандарта.
Re[5]: псевдоним template класса с незаданным параметром?
От: Василий Зверев Россия  
Дата: 04.12.08 08:31
Оценка:
W>>>Врядли. У умного указателя наверняка имеются кастомные конструкторы и операторы присваивания.
AG>>Конструкторы, кроме копирования — зафорвардить вручную, оператор = сам сгенерится.
AG>>Конечно, для смартпоинтера это плохой вариант, но луше не знаю
Спасибо за ответы.
Как временное решение я так и сделал: создал класс-наследник и прописал в нём все конструкторы (их у меня пока два). Но чем больше приходится писать, тем больше ошибок можно посадить. И поддерживать сложнее, если понадобится добавить новый конструктор.
Понравилось решение от Were и byleas с объявлением типа в новом шаблоне. Сегодня поменяю код

E>только как-то не понятно на кой это всё надо? Может быть каким-то уже готовым смартпоинтером стоит попользоваться? Там много прикольного уже люди напридумывали, вообще-то...

Можете что-то посоветовать, что уже сами опробовали и понравилось?
Мой смартпоинтер умеет не только освобождать память, но и закрывать handle различных типов (мой проект активно использует Win32 API).
Re[6]: псевдоним template класса с незаданным параметром?
От: matcode Беларусь  
Дата: 04.12.08 08:59
Оценка:
Здравствуйте, Василий Зверев, Вы писали:

ВЗ>Можете что-то посоветовать, что уже сами опробовали и понравилось?

ВЗ>Мой смартпоинтер умеет не только освобождать память, но и закрывать handle различных типов (мой проект активно использует Win32 API).

Тут статья как раз по вашей теме.
Re[7]: псевдоним template класса с незаданным параметром?
От: matcode Беларусь  
Дата: 04.12.08 09:00
Оценка:
Сорри. Здесь.
Re: псевдоним template класса с незаданным параметром?
От: Аноним  
Дата: 04.12.08 10:50
Оценка: :)))
Нет.

В новом стандарте это, может быть, и введут, но кому он нужен этот новый стандарт? К тому времени, когда все компиляторы будут его поддерживать, уже сам C++ умрет.
Re[6]: псевдоним template класса с незаданным параметром?
От: Erop Россия  
Дата: 04.12.08 16:22
Оценка:
Здравствуйте, Василий Зверев, Вы писали:

ВЗ>Мой смартпоинтер умеет не только освобождать память, но и закрывать handle различных типов (мой проект активно использует Win32 API).


А какие библиотеки доступны?
Просто auto_ptr он как идея не того, не очень хорош...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: псевдоним template класса с незаданным параметром?
От: Юрий Жмеренецкий ICQ 380412032
Дата: 05.12.08 05:36
Оценка:
Здравствуйте, Василий Зверев, Вы писали:
...
ВЗ>Мой смартпоинтер умеет не только освобождать память, но и закрывать handle различных типов (мой проект активно использует Win32 API).

А так умеет ?
void foo(auto_free_ptr<PTR>); 
//...

auto_heap_ptr<PTR> p = ...;
foo(p);

Это я к тому что политика освобождения является частью типа(иногда это надо, зачастую — нет). Функции оперирующей с указателем обычно все равно, откуда взялся указатель и как он будет удален. А для какой-нибудь функции-фабрики метод выделения памяти — деталь реализации.

Еще замечание — все пользователи auto_heap_ptr должны знать про HeapFree(хотя можно конечно вручную писать extern'ы, или переходники). В принципе не проблема если заточено специально под winapi.

Умные указатели надо писать после ознакомления с реализацией boost::shared_ptr =)
Там есть непрозрачный(т.е. про HeapFree клиентам зать не нужно вообще) custom deleter который не является частью типа.
Минусы у него(shared_ptr) есть — но это цена за гибкость(type-erasure в частности).

Про winapi handle — иногда нужен явный контроль освобождения для обработки ошибок. Бустовцы в этом месте схитрили — у них в документации используется 'void fclose(FILE * f)' и 'void CloseHandle(HANDLE)'
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.