May. 4th, 2012

madf: (Default)
Замутив на роботі круту шнягу із std::function, lambda, auto, std::bind і variadic templates.
Чесно кажучи, все це хак щоб обійти обмеження архітектури а-ля 90-ті. У нормальних умовах вистачило б std::bind.
Але сама можливість таких трюків надає відчуття всемогутності!

Всього-то треба було додати post-assign callback до певного application field. І все б нічого, тільки вказівник на об’єкт-holder має тип void *. Спочатку додав власне callback типу std::function<void (void *)>. Потім додав статичний метод-адаптер приблизно такий:
template <class C, typename ... Us, typename ... Vs>
std::function<void (void *)> adaptMethod(void (C::* method) (Us ...), Vs ... vs)
{
    auto temp(std::bind(method, std::placeholders::_1, vs ...));
    return [temp] (void * objPtr) { temp(static_cast<C *>(objPtr)); };
}

Роздільні типи Us і Vs потрібні для неявного перетворення типів (наприклад enum -> int). std::bind у temp потрібен бо gcc 4.6.1 ще не вміє захоплювати у лямбду пакунок параметрів і його треба зв’язати до передачі в лямбду.
Але ставити callback так:
appField.setPostAssignCallback(AppField::adaptMethod(&HoldSwap::setNotlDivMult, LEG1)) - не дуже зручно (хоча без адаптора було б гірше). Тому я ще зробив overload для setPostAssignCallback:
template <class C typename ... Us, typename ... Vs>
void setPostAssignCallback(void (C::* method) (Us ...), Vs ... vs) { setPostAssignCallback(adaptMethod(method, vs ...)); }

І тепер ставити callback можна просто:
appField.setPostAssignCallback(&HoldSwap::setNotlDivMult, LEG1);
Треба б ще параметри std::move-нути, але rvalue references не така проста штука як здається. Як буде час - напишу про них і про std::move/std::forward.

На фоні тупого багофіксингу писати таке було надзвичайно приємно. Головне щоб воно через рев’ю пройшло.

Profile

madf: (Default)
madf

April 2018

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 30th, 2025 10:36 am
Powered by Dreamwidth Studios