Мысль о BOOST_SCOPE_EXIT и лямбдах
От: Alexander G Украина  
Дата: 04.09.08 21:59
Оценка:
Пример из документации:
m_persons.push_back(person);
BOOST_SCOPE_EXIT( (commit)(m_persons) )
{
    if(!commit)
        m_persons.pop_back();
} BOOST_SCOPE_EXIT_END


Фактически, переменные commit и m_persons захватываются по ссылке и передаются как параметры статического метода, тело которого находится между макросами.

Есть идея применить похожий подход для иммитации замыканий. Вместо деструктора тогда будет задаваться оператор().
CLOSURE(int, (int i)(int j), (a)(b), (x)(y) )
{
  // myFunction - имя перменной, int(int i, int j) - сигнатура.
  // допустим, a, b - захват по ссылке, x, y - по значению.
  ...
} CLOSURE_END(myFunction)


Возникнет следующая трудность: шаблоны нельзя параметризовать локальными классами. Т.е. в std::for_each нельзя будет передать myFunction, если она типа локального класса (хотя в MSVC можно).

Однако, проблема вроде решима. Структуру, хранящую ссылки на параметры, можно заменить на boost::tuple. Вложенный класс со статическим методом остаётся, но переменная myFunction не этого класса, а не-локального шаблонного класса. этот не-локальный шаблонный класс содержит три шаблонных параметра: сигнатура, tuple c параметрами и статический метод локального класса. Типа так:
typedef struct сгенерированное_имя1 {
  typedef detail::closure_functor<
    R (формальные параметры), // тип оператора() 
    boost::tuple<заxваченные>,
    R Body( формальные параметры, заваченные )
  > functor_t;

 R Body( формальные параметры, заваченные )
 { код между макросами } 
} сгенерированное_имя2;

сгенерированное_имя2::functor_t myFunction(сгенерированное_имя2::Body, конструктор_тупла);

Т.е. сам локальный класс в шаблонах не используется.

Есть ли какие-либо очевидные проблемы (кроме сложности реализации) ? Кто-нибудь пробовал такое реализовать ?
Русский военный корабль идёт ко дну!
Re: Мысль о BOOST_SCOPE_EXIT и лямбдах
От: jazzer Россия Skype: enerjazzer
Дата: 05.09.08 00:10
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Пример из документации:

AG>
AG>m_persons.push_back(person);
AG>BOOST_SCOPE_EXIT( (commit)(m_persons) )
AG>{
AG>    if(!commit)
AG>        m_persons.pop_back();
AG>} BOOST_SCOPE_EXIT_END
AG>


AG>Фактически, переменные commit и m_persons захватываются по ссылке и передаются как параметры статического метода, тело которого находится между макросами.


AG>Есть идея применить похожий подход для иммитации замыканий. Вместо деструктора тогда будет задаваться оператор().


Собственно, это обсуждалось во время review библиотеки, посмотри в списке рассылки.
Как обычно, Стивен Ватанабе пришел с совершенно безумными решениями, Александреску отдыхает

Алекс Насонов сейчас как раз и работает над тем, чтобы сделать полноценную библиотеку с замыканиями и локальными функциями.
Так что если тебя эта тема интересует, можешь поговорить с ним непосредственно.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Ещё одна мысль туда же
От: Alexander G Украина  
Дата: 05.09.08 07:44
Оценка:
Не прикручивать захват. Захват делать вручную биндом.
Тогда всё просто

#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)

#define LOCAL(R, P) \
  typedef struct ANONYMOUS_VARIABLE(xg1) { typedef R(*F) P; static R body P { 

#define LOCAL_END(name) \
  } } ANONYMOUS_VARIABLE(xg2); \
  const ANONYMOUS_VARIABLE(xg2)::F name = ANONYMOUS_VARIABLE(xg2)::body;

int main()
{
  LOCAL(bool, (int i, int j, bool reverse))
    return reverse ? (j < i) : (i < j);
  LOCAL_END(myFcn)
  int a[] = { 2, 5, 1, 6 };
  std::sort(a, a + sizeof(a)/sizeof(a[0]), boost::bind(myFcn, _1, _2, true));
}
Русский военный корабль идёт ко дну!
Re[2]: Мысль о BOOST_SCOPE_EXIT и лямбдах
От: Alexander G Украина  
Дата: 05.09.08 07:45
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Собственно, это обсуждалось во время review библиотеки, посмотри в списке рассылки.

J>Как обычно, Стивен Ватанабе пришел с совершенно безумными решениями, Александреску отдыхает

Нашёл обсуждение замыканий, но безумных решений Стивена не увидел.
Есть ли вообще удобный способ искать по этим рассылкам ?

J>Алекс Насонов сейчас как раз и работает над тем, чтобы сделать полноценную библиотеку с замыканиями и локальными функциями.

J>Так что если тебя эта тема интересует, можешь поговорить с ним непосредственно.

ок.
Русский военный корабль идёт ко дну!
Re[3]: Мысль о BOOST_SCOPE_EXIT и лямбдах
От: jazzer Россия Skype: enerjazzer
Дата: 05.09.08 07:54
Оценка: 15 (1) :)
Здравствуйте, Alexander G, Вы писали:

AG>Есть ли вообще удобный способ искать по этим рассылкам ?

боюсь, что нету.
Это тебе не RSDN

AG>Нашёл обсуждение замыканий, но безумных решений Стивена не увидел.

Ну вот, например.
Одна из самых безумных вещей в С++, которые я видел: http://article.gmane.org/gmane.comp.lib.boost.devel/168837/

На всякий случай приведу код здесь, помедитируй над ним, прежде чем читать разъяснение — получишь большое интеллектуальное удовольствие

typedef char no;
struct yes { no dummy[2]; };

template<bool>
struct conditional_declare;

struct undeclared {};

template<>
struct conditional_declare<true> {
    template<int>
    struct apply {
        void* value;
        friend void operator>(bool, const apply&) {}
    };
};

template<>
struct conditional_declare<false> {
    static const int apply = 0;
};

template<class T>
yes is_declared(const T&);
no is_declared(const undeclared&);

undeclared local_function_bound_args;

#define BOOST_LOCAL_FUNCTION_DECLARE_ARGS() \
     conditional_declare<sizeof(is_declared(local_function_bound_args)) == \
     sizeof(no)>::apply<0> local_function_bound_args

int main() {
    BOOST_LOCAL_FUNCTION_DECLARE_ARGS(); // declares local_function_bound_args
    BOOST_LOCAL_FUNCTION_DECLARE_ARGS(); // turns into a pair of comparisons
}
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Мысль о BOOST_SCOPE_EXIT и лямбдах
От: Alexander G Украина  
Дата: 05.09.08 08:15
Оценка:
Здравствуйте, jazzer, Вы писали:

J>На всякий случай приведу код здесь, помедитируй над ним, прежде чем читать разъяснение — получишь большое интеллектуальное удовольствие


Там спойлер в комментариях в main, но всё равно удовольствие получил
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.