Есть дескриптор, есть функции создания-закрытия дескриптора, и функции для работы с дескриптором.
Цель — объект-обертка, который держит дескриптор и при выходе из области видимости его закрывает.
Если дескриптор имеет тип "указатель на что-нибудь", то с этим прекрасно справляется std::unique_ptr, например:
std::unique_ptr<FILE, int(*)(FILE*)> myfile(fopen("xxx.txt", "rb"), fclose); — и дальше работаем с файлом, не боясь потерять его закрытие.
Для типов-не-указателей std::unique_ptr не подходит.
Например, дескрипторы файлов в linux имеют тип int: int f = open("xxx.txt", O_RDONLY, 0); close(f);
Писать обертки-велосипеды я умею, в том числе шаблонные, если готовых решений нет, то придется так и делать.
Вопросы:
1. Есть ли готовые решения, чтоб держать дескриптор типа, например, int? (RAII)
2. Какими решениями пользуетесь вы, когда вам нужно держать дескриптор типа-не-указателя, чтоб не потерять его закрытие?
Здравствуйте, antonio_banderas, Вы писали:
_>1. Есть ли готовые решения, чтоб держать дескриптор типа, например, int? (RAII) _>2. Какими решениями пользуетесь вы, когда вам нужно держать дескриптор типа-не-указателя, чтоб не потерять его закрытие?
Здравствуйте, Abyx, Вы писали:
_>>Для типов-не-указателей std::unique_ptr не подходит. A>подходит. у deletera'а надо определить pointer
A>
A>struct my_deleter {
A> typedef pointer int;
A> void operator()(pointer x) { my_close(x); }
A>};
A>std::unique_ptr<int, my_deleter> p;
A>
Идея хорошая, но пока не работает:
struct IntFileCloserDeleter
{
typedef int pointer;
void operator()(pointer x) { if (x != -1) ::close(x); }
};
int file1 = ::open(filenameOutput, O_WRONLY|O_CREAT|O_TRUNC, 0);
std::unique_ptr<int, IntFileCloserDeleter> filecloser { file1 };
/usr/include/c++/4.8/bits/unique_ptr.h: In instantiation of 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = int; _Dp = IntFileCloserDeleter]':
/home/antonio/workspace/...............cpp:55:78: required from here
/usr/include/c++/4.8/bits/unique_ptr.h:183:12: error: invalid operands of types 'int' and 'std::nullptr_t' to binary 'operator!='
if (__ptr != nullptr)
Здравствуйте, Abyx, Вы писали:
A>Здравствуйте, antonio_banderas, Вы писали:
_>>Идея хорошая, но пока не работает:
_>> if (__ptr != nullptr)
_>>g++ 4.8.1 with flag -std=c++11
A>это баг gcc.
Читать стандарт, чтоб выяснить, у кого баг, в гцц или в коде, некогда, да и, на самом деле, какая разница, если оно всё равно от этого работать не станет.
Поскольку gcc ближе всех следует стандарту (насколько я знаю), решение можно признать не рабочим — будь то только де-факто, или де-юро тоже.
Еще коллега мнение высказал, что объявлять int поинтером — это грязный хак (насчет грязного не согласен). Возможно, gcc аналогичного мнения, и потому фейлит это.
Здравствуйте, antonio_banderas, Вы писали:
_>Вопросы: _>1. Есть ли готовые решения, чтоб держать дескриптор типа, например, int? (RAII) _>2. Какими решениями пользуетесь вы, когда вам нужно держать дескриптор типа-не-указателя, чтоб не потерять его закрытие?
В общем пока обошелся написанным за несколько минут велосипедом:
Здравствуйте, okman, Вы писали:
O>Здравствуйте, antonio_banderas, Вы писали:
_>>1. Есть ли готовые решения, чтоб держать дескриптор типа, например, int? (RAII) _>>2. Какими решениями пользуетесь вы, когда вам нужно держать дескриптор типа-не-указателя, чтоб не потерять его закрытие?
O>BOOST_SCOPE_EXIT либо аналоги. O>http://www.boost.org/doc/libs/1_50_0_beta1/libs/scope_exit/doc/html/BOOST_SCOPE_EXIT.html
Слишком сложно.
Я за пару минут так и не понял, как его надо использовать. В документации подходящих примеров не нашел.
Наверно, в некоторых кругах считается, что чем более сложными конструкциями пользуется человек, тем он круче, но я предпочитаю обратный подход: чем проще — тем лучше.
Самодельный велосипед (см. сообщение ниже) занял несколько минут.
Здравствуйте, Abyx, Вы писали:
_>>Для типов-не-указателей std::unique_ptr не подходит. A>подходит. у deletera'а надо определить pointer
Проблема в том, что выделенным нуль-значением он считает 0.
Что, в случае с дескрипторами, не обязательно справедливо. Там выделенным значением бывает -1, а 0 — рядовым.
Чтобы обойти это, придётся использовать обёртку. Заодно и багофичу gcc обойти получится
Здравствуйте, antonio_banderas, Вы писали:
_>2. Какими решениями пользуетесь вы, когда вам нужно держать дескриптор типа-не-указателя, чтоб не потерять его закрытие?
Здравствуйте, antonio_banderas, Вы писали:
_>1. Есть ли готовые решения, чтоб держать дескриптор типа, например, int? (RAII)
BOOST_SCOPE_EXIT, лично я его не использую
_>2. Какими решениями пользуетесь вы, когда вам нужно держать дескриптор типа-не-указателя, чтоб не потерять его закрытие?
a) пишу класс, который в деструкторе освобождает ресурсы.
b) еще можно int скопировать в динамическую память
Здравствуйте, antonio_banderas, Вы писали:
_>Здравствуйте, Abyx, Вы писали:
A>>Здравствуйте, antonio_banderas, Вы писали:
_>>>Идея хорошая, но пока не работает:
_>>> if (__ptr != nullptr)
_>>>g++ 4.8.1 with flag -std=c++11
A>>это баг gcc.
_>Читать стандарт, чтоб выяснить, у кого баг, в гцц или в коде, некогда, да и, на самом деле, какая разница, если оно всё равно от этого работать не станет. _>Поскольку gcc ближе всех следует стандарту (насколько я знаю), решение можно признать не рабочим — будь то только де-факто, или де-юро тоже. _>Еще коллега мнение высказал, что объявлять int поинтером — это грязный хак (насчет грязного не согласен). Возможно, gcc аналогичного мнения, и потому фейлит это.
да, всетаки это не баг. указатель должен удовлетворять требованиям NullPointer а туда входит сравнение с nullptr
Здравствуйте, antonio_banderas, Вы писали:
_>Для типов-не-указателей std::unique_ptr не подходит. _>Например, дескрипторы файлов в linux имеют тип int: int f = open("xxx.txt", O_RDONLY, 0); close(f);
Обычно я пишу отдельный класс под каждый случай, но иногда думаю вот в этом направлении:
int handle = open("xxx.txt", O_RDONLY, 0);
auto FunOnExit = [](int* pHandle){ return close(*pHandle); };
std::unique_ptr<int, decltype(FunOnExit)> myfile(&handle, FunOnExit);
Здравствуйте, fin_81, Вы писали:
_>Думаю так нельзя, потому что неизвестно как надо реализовать operator bool для unique_ptr для не указателя.
Почему, для FILE* известно, а для int неизвестно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Тогда уж проще сделать нормальную RAII-обёртку.
Плохо, что её так и не появилось в std, ну да это же обычная история не?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Тогда уж проще сделать нормальную RAII-обёртку.
Разумеется!
E>Плохо, что её так и не появилось в std, ну да это же обычная история не?
Это заговор!
Не захотели вдобавок к указателям на объект и указателям на массив сделать семейство дескрипторов.
Был бы unique_ptr/unique_array/unique_handle и shared_ptr/shared_array/shared_handle
Всего-то и нужно, — трейтс "что такое нуль и что с этим делать".
Здравствуйте, Erop, Вы писали:
_>>Думаю так нельзя, потому что неизвестно как надо реализовать operator bool для unique_ptr для не указателя.
E>Почему, для FILE* известно, а для int неизвестно?
Ну вот КО мне подсказывает, потому, что FILE* это указатель.
С указателями unique_ptr прекрасно работает.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, fin_81, Вы писали:
_>>Думаю так нельзя, потому что неизвестно как надо реализовать operator bool для unique_ptr для не указателя.
E>Почему, для FILE* известно, а для int неизвестно?
Потому что "умные владельцы" почему-то спроектированы так, что логика владения сильно связана с самим объектом. Если у объекта нет специально значения для "несуществующего объекта" (NULL, nullptr и тп), то получается что владеть этим объектом невозможно. Похоже на то, что застряли между C и C++
Здравствуйте, antonio_banderas, Вы писали:
_>Ну вот КО мне подсказывает, потому, что FILE* это указатель. _>С указателями unique_ptr прекрасно работает.
Ну вот мне КО подсказывает, что это потому, что в комитете опять протупили, а не потому, что "не известно"
Единственная беда с числами, в качестве хендлов -- неизвестно какое значение является валидным пустым. Ну так могли сделать параметром шаблона или трита...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском