Comments 27
Реализация класса scoped_resource настолько проста и элегантна, что даже чем-то напомнила мне идею Y-combinator'a.Так где код-то?
Ожидал для себя увидеть не примеры использования, а основные идеи самой реализации да и просто сам код.
да вот же она, реализация! см. последний <code/code>.
все же хотелось не просто давать ответы, а и подтолкнуть к решению.
сам только решив эту задачу осознал насколько важно правильно поставить вопрос, который звучал так:
все же хотелось не просто давать ответы, а и подтолкнуть к решению.
сам только решив эту задачу осознал насколько важно правильно поставить вопрос, который звучал так:
try
{
int fd = ::open("file", ...);
// i don't wrap it no more time
throw exception();
}
catch(exception&)
{
// oh no
}
Похоже на Boost.Scope Exit?
В последней версии они тоже пишут, как можно сделать подобное с лямбдой.
В последней версии они тоже пишут, как можно сделать подобное с лямбдой.
А зачем вносить инициализацию в функтор — это лишнее усложнение.
Гораздо понятнее, когда есть только деструктор:
намного легче понять и начать использовать.
Шаблон 'finally' правда хитрый, без препроцессора не обошлось (юзается __COUNTER__ и генерируется уникальное имя холдеру, чтобы не выдумывать самому, как это сделао в последней ссылке)
Гораздо понятнее, когда есть только деструктор:
FILE* f = fopen("file", "rb");
if(!f) throw FileException();
finally([&f] { fclose(f); });
// reading file...
BeginUpdate();
finally([this] { EndUpdate(); });
// updating...
намного легче понять и начать использовать.
Шаблон 'finally' правда хитрый, без препроцессора не обошлось (юзается __COUNTER__ и генерируется уникальное имя холдеру, чтобы не выдумывать самому, как это сделао в последней ссылке)
sqlite3* db;
sqlite3_open("some.db", &db);
scope(exit) sqlite3_close(db);
;)
Александреску жжот, конечно. Но это выглядит неконсистентным. Не?
Неконсистентным с чем?
само понятие блока скоупа конфликтует с языком где есть gc. в D ведь есть gc?
Понятие scope ортогонально наличию gc. В D есть gc. есть стек, есть malloc. А так же множество других ресурсов помимо памяти, которые нужно освобождать (файловые дескрипторы, сокеты и т.п.). Т.к. все классы — ссылочные типы, это даже не конфликтует с привычной по C++ семантикой, там ведь тоже указатели не освобождаются при выходе из scope и вроде никого это не беспокоит.
Ничего не конфликтует. Деструктор же не имеет отношения к памяти. Он просто выполняет некоторый код, когда обьект становится недоступен системе.
инициализатор вида std::function нужен по двум причинам:
1. lazy, если это нужно
2. нормальная редукция самого инициализатора, когда нужен код, который ближе к wrapped чем сам хак.
в моем примере это видно там, где mutex…
короче, это более предсказуемо в плане sequence point, но также позволяет использовать инплейсные лямбды, без их вызова, что усложняет чтение кода. все написанное и есть о том как избежать первым параметром T, а применить λx.T.
1. lazy, если это нужно
2. нормальная редукция самого инициализатора, когда нужен код, который ближе к wrapped чем сам хак.
в моем примере это видно там, где mutex…
короче, это более предсказуемо в плане sequence point, но также позволяет использовать инплейсные лямбды, без их вызова, что усложняет чтение кода. все написанное и есть о том как избежать первым параметром T, а применить λx.T.
не минусуйте, пожалуйста, комментаторов.
этоа статья задумывалась как «пост добра», где каждый находит свой дзэн C++.
где однозначного вывода нету, будь вы коммитером boost.phoenix или первокурсником со struct something {};
этоа статья задумывалась как «пост добра», где каждый находит свой дзэн C++.
где однозначного вывода нету, будь вы коммитером boost.phoenix или первокурсником со struct something {};
Зачем там везде типы. Используйте auto.
scoped_resource(const scoped_resource&) = delete;
А что за "= delete"? это из последнего стандарта фича? извините, просто давно на С++ активно не писал.
А что за "= delete"? это из последнего стандарта фича? извините, просто давно на С++ активно не писал.
прикольно, но чем отличается от shared_ptr c deleter?
Или же это способ показать как можно сильно упростить задачу с С++ 0х11 без всяких bind? Это же прототип? Так как подсчета ссылок нету.
Или же это способ показать как можно сильно упростить задачу с С++ 0х11 без всяких bind? Это же прототип? Так как подсчета ссылок нету.
> прикольно, но чем отличается от shared_ptr c deleter?
тем, что shared_ptr всегда выделяет память в куче, плюс поддерживает счётчик ссылок. unique_ptr — тоже выделяет память под объект. scoped_ptr (boost?) с deleter'ом был бы аналогом, вот только есть разница между
и
Первое лаконичнее, хотя вариант с «func, arg1, arg2» может сбить с толку без привычного «func(arg1, arg2)».
тем, что shared_ptr всегда выделяет память в куче, плюс поддерживает счётчик ссылок. unique_ptr — тоже выделяет память под объект. scoped_ptr (boost?) с deleter'ом был бы аналогом, вот только есть разница между
ha::scoped_resource<int, char*, int> fd(::open, filename.c_str(), O_RDONLY, ::close);
и
scoped_ptr<int> fd(::open(filename.c_str(), O_RDONLY), [](int fd_) { ::close(fd_); });
Первое лаконичнее, хотя вариант с «func, arg1, arg2» может сбить с толку без привычного «func(arg1, arg2)».
Как-то очень уж вычурно.
Почему бы не засунуть освобождение ресурсов в лямбду или любую другую сущность с operator() без параметров? Или иначе статьи для хабра состряпать не получилась бы?
Вот вариант для Objective-C.
Header
Implementation
Где-то в закромах валялся такой же, но на шаблонах и для любого объекта-функции. Работал задолго до появления C++11. Если будет интерес — откопаю да выложу «на посмотреть».
Почему бы не засунуть освобождение ресурсов в лямбду или любую другую сущность с operator() без параметров? Или иначе статьи для хабра состряпать не получилась бы?
Вот вариант для Objective-C.
Header
Implementation
Где-то в закромах валялся такой же, но на шаблонах и для любого объекта-функции. Работал задолго до появления C++11. Если будет интерес — откопаю да выложу «на посмотреть».
> finit_(finit), final_(final), resource_(finit_(args...))
как лаконично.
как лаконично.
Sign up to leave a comment.
RAII + С++ variadic templates = win