scope_exit
От: jyuyjiyuijyu  
Дата: 12.12.15 05:04
Оценка: 2 (1)
привет

подумал (возможно ошибочно) удобно было бы совместить loki_on_block_exit и boost_scope_exit
как вам? (работает под MSVC)


возможный юзкейс

юзаем как в loki
HDESK hDesk = CreateDesktop(desktopName , NULL, NULL, 0, DESKTOP_SWITCHDESKTOP|
        DESKTOP_WRITEOBJECTS|
        DESKTOP_READOBJECTS|
        DESKTOP_ENUMERATE|
        DESKTOP_CREATEWINDOW|
        DESKTOP_CREATEMENU, NULL);

scope_exit(CloseDesktop(hDesk));


юзаем как в boost_scope_exit
if (CreateProcess(NULL, (LPSTR)"***.exe args", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &procInfo)) {

    scope_exit() {
        CloseHandle(procInfo.hThread);
        CloseHandle(procInfo.hProcess);
    };


вот реализация

#ifndef X13_SCOPEGUARD_INC_
#define X13_SCOPEGUARD_INC_

#include <boost/preprocessor/cat.hpp>

namespace x13scopeguard
{
    template<typename F>
    class ScopeExit
    {
    public:
        ScopeExit(const F& fn) : m_fn(fn) {;}
        ~ScopeExit()
        {
            m_fn();
        }
    private:
        F m_fn;
    };


    class ScopeExitCreator
    {
    public:
        template<typename Fn>
        ScopeExit<Fn> operator << (const Fn &fn)
        {
            return ScopeExit<Fn>(fn);
        }
    };
}

#define SCOPE_EXIT_CAT(...) , ## __VA_ARGS__ 

#define SCOPE_EXIT_COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _
#define SCOPE_EXIT_REPEAT_PARAMS(...) (__VA_ARGS__)
#define SCOPE_EXIT_COUNT_PARMS(...) SCOPE_EXIT_COUNT_PARMS2 \
    SCOPE_EXIT_REPEAT_PARAMS(SCOPE_EXIT_CAT(__VA_ARGS__) 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

#define SCOPE_EXIT_LAMBDA2() const auto  &BOOST_PP_CAT(scope_exit_guard_,__LINE__) = \
    x13scopeguard::ScopeExitCreator() << [&]()

#define SCOPE_EXIT_LAMBDA(...) BOOST_PP_IF(SCOPE_EXIT_COUNT_PARMS(__VA_ARGS__), \
    SCOPE_EXIT_LAMBDA2() { __VA_ARGS__; }, SCOPE_EXIT_LAMBDA2())

#define scope_exit(...) SCOPE_EXIT_LAMBDA(__VA_ARGS__)

#endif
Re: scope_exit
От: bnk СССР http://unmanagedvisio.com/
Дата: 12.12.15 08:24
Оценка: -1
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>привет


J>подумал (возможно ошибочно) удобно было бы совместить loki_on_block_exit и boost_scope_exit

J>как вам? (работает под MSVC)



Поясню.
scope_exit/loki_on_block_exit уже затычки на недоработку языка (отсутствие "using")
Улучшение этих костылей с помощью препроцессора — фейспалм.
Re[2]: scope_exit
От: jyuyjiyuijyu  
Дата: 12.12.15 08:51
Оценка:
Здравствуйте, bnk, Вы писали:

bnk>


bnk>Поясню.

bnk>scope_exit/loki_on_block_exit уже затычки на недоработку языка (отсутствие "using")
bnk>Улучшение этих костылей с помощью препроцессора — фейспалм.

да макросы они повсюду в C/C++, а так вроде удобно получилось
Re: scope_exit
От: B0FEE664  
Дата: 12.12.15 13:07
Оценка: -1
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>как вам? (работает под MSVC)


Плохо. Макросы не нужны. Вот тут есть нормальное решение.
Автор: Evgeny.Panasyuk
Дата: 19.03.15
И каждый день — без права на ошибку...
Re[2]: scope_exit
От: BulatZiganshin  
Дата: 12.12.15 17:28
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Плохо. Макросы не нужны. Вот тут есть нормальное решение.
Автор: Evgeny.Panasyuk
Дата: 19.03.15


я правилоьно понимаю, что все эти хитроумные решения — только ради экономии скобок, а обычную лямбду туда сунуть без проблем? типа

#include <stdio.h>
#include <functional>

struct on_exit
{
  std::function<void (void)> f;
  ~on_exit() {f();}
};

int main()
{
  on_exit _ {[&]{printf("on_exit\n");}};
  printf("start\n");
}
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: scope_exit
От: Evgeny.Panasyuk Россия  
Дата: 12.12.15 17:33
Оценка: +1
Здравствуйте, BulatZiganshin, Вы писали:

BZ>а обычную лямбду туда сунуть без проблем? типа

BZ>
BZ>  std::function<void (void)> f;
BZ>


Лишнее стирание типа.
Отредактировано 12.12.2015 17:34 Evgeny.Panasyuk . Предыдущая версия .
Re[4]: scope_exit
От: BulatZiganshin  
Дата: 12.12.15 18:26
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

BZ>> std::function<void (void)> f;

EP>Лишнее стирание типа.

а как?? я не являюсь глубоким знатоком c++, пробовал сделать template — не вышло. и вообще удобней было бы присваивание

on_exit _ = [&]{printf("on_exit\n");};

но я не знаю как описать тип для этого
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: scope_exit
От: Evgeny.Panasyuk Россия  
Дата: 12.12.15 19:11
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>а как?? я не являюсь глубоким знатоком c++, пробовал сделать template — не вышло. и вообще удобней было бы присваивание

BZ>on_exit _ = [&]{printf("on_exit\n");};
BZ>но я не знаю как описать тип для этого

Нужно через функцию посредника. То есть on_exit будет шаблоном, но тип в этот шаблон будет подставлять функция посредник. Использование вот такое:
auto &&temp = make_on_exit([&]{printf("on_exit\n");});

Либо не обычная функция, а какой-нибудь оператор типа умножения, тогда будет вот так:
auto &&temp = auxiliary{} * [&]{printf("on_exit\n");};
В этом случае левую часть можно поместить в макрос (в котором также будет генерироваться имя temp), тогда будет вот так:
scope_exit {printf("on_exit\n");};
Полный пример вот тут.

Подробно от Александреску:
http://www.youtube.com/watch?v=WjTrfoiB0MQ
Re[6]: scope_exit
От: _hum_ Беларусь  
Дата: 13.12.15 15:51
Оценка:
Здравствуйте, Evgeny.Panasyuk,
а как все-таки решается проблема с использованием в лямдах-обработчиках on_exit локальных имен, объявленных не в начале, а в середине scope?
Re[7]: scope_exit
От: Evgeny.Panasyuk Россия  
Дата: 13.12.15 16:16
Оценка:
Здравствуйте, _hum_, Вы писали:

__>а как все-таки решается проблема с использованием в лямдах-обработчиках on_exit локальных имен, объявленных не в начале, а в середине scope?


Если инициализировать перед scope_exit никак нельзя, тогда можно обернуть в boost::optional — то есть лямбда захватит этот optional, а сама инициализация будет в середине scope. Но, ИМХО, это редкая ситуация.
Re[2]: scope_exit
От: Sni4ok  
Дата: 22.12.15 15:34
Оценка: :))
Здравствуйте, B0FEE664, Вы писали:

BFE>Макросы не нужны.


сначала не нужны макросы, потом goto, а потом вы заберёте у нас порно и бухло
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.