Лямбду в WinAPI
От: Слава Израиль  
Дата: 28.03.11 05:41
Оценка:
Здравствуйте.

А можно как нибудь заставить работать такое:

HWND FindApplicationWindow()
{
    HWND foundHWnd = 0;
    DWORD procID = GetCurrentProcessId();
    EnumWindows([&foundHWnd,&procID](HWND hWnd, LPARAM lParam) -> BOOL
    {
        /*
         ********************************************
         */
        return TRUE;
    },
    0);
}


error C2664: 'EnumWindows' : cannot convert parameter 1 from '`anonymous-namespace'::<lambda0>' to 'WNDENUMPROC'

Спасибо за внимание
Re: Лямбду в WinAPI
От: ilnar Россия  
Дата: 28.03.11 05:45
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте.


С>А можно как нибудь заставить работать такое:


С>
С>HWND FindApplicationWindow()
С>{
С>    HWND foundHWnd = 0;
С>    DWORD procID = GetCurrentProcessId();
С>    EnumWindows([&foundHWnd,&procID](HWND hWnd, LPARAM lParam) -> BOOL
С>    {
С>        /*
С>         ********************************************
С>         */
С>        return TRUE;
С>    },
С>    0);
С>}
С>


С>

С>error C2664: 'EnumWindows' : cannot convert parameter 1 from '`anonymous-namespace'::<lambda0>' to 'WNDENUMPROC'


сделай фугкцию обертку.
лямбда функции это объекты с перегруженным оператором, а WINAPI хочет чистые функции с с особой конвенцией вызова
Re[2]: Лямбду в WinAPI
От: Слава Израиль  
Дата: 28.03.11 05:48
Оценка:
Здравствуйте, ilnar, Вы писали:

I>сделай фугкцию обертку.

I>лямбда функции это объекты с перегруженным оператором, а WINAPI хочет чистые функции с с особой конвенцией вызова

Ну тогда проще будет по старинке.
Спасибо за внимание
Re: Лямбду в WinAPI
От: alexeiz  
Дата: 28.03.11 07:33
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте.


С>А можно как нибудь заставить работать такое:


С>
С>HWND FindApplicationWindow()
С>{
С>    HWND foundHWnd = 0;
С>    DWORD procID = GetCurrentProcessId();
С>    EnumWindows([&foundHWnd,&procID](HWND hWnd, LPARAM lParam) -> BOOL
С>    {
С>        /*
С>         ********************************************
С>         */
С>        return TRUE;
С>    },
С>    0);
С>}
С>


С>

С>error C2664: 'EnumWindows' : cannot convert parameter 1 from '`anonymous-namespace'::<lambda0>' to 'WNDENUMPROC'


Убери capture parameters [&foundHWnd, &procID], и тогда будет работать. Например:
typedef int (*func)(int);

int foo(func f)
{
    return f(10);
}

int main()
{
    return foo([](int a) { return 2 * a; });
}
Re[2]: Лямбду в WinAPI
От: Слава Израиль  
Дата: 28.03.11 07:38
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Убери capture parameters [&foundHWnd, &procID], и тогда будет работать. Например:

A>
A>typedef int (*func)(int);

A>int foo(func f)
A>{
A>    return f(10);
A>}

A>int main()
A>{
A>    return foo([](int a) { return 2 * a; });
A>}
A>


Ну во первых они мне нужны, без них проще и короче будет по старому.
А во вторых, можешь обяснить причину такого поведения?
Спасибо за внимание
Re[3]: Лямбду в WinAPI
От: _nn_  
Дата: 28.03.11 07:48
Оценка: 4 (1)
Здравствуйте, Слава, Вы писали:

С>А во вторых, можешь обяснить причину такого поведения?


По стандарту:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3052.html

Если нет захваченных аргументов, то есть преобразование в указатель на функцию.

5.1.2.6

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const
conversion function to pointer to function having the same parameter and return types as the closure type’s
function call operator. The value returned by this conversion function shall be the address of a function
that, when invoked, has the same effect as invoking the closure type’s function call operator.

http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Лямбду в WinAPI
От: ilnar Россия  
Дата: 28.03.11 07:54
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, Слава, Вы писали:


С>>А во вторых, можешь обяснить причину такого поведения?


__>По стандарту:

__>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3052.html

__>Если нет захваченных аргументов, то есть преобразование в указатель на функцию.


__>5.1.2.6

__>

__>The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const
__>conversion function to pointer to function having the same parameter and return types as the closure type’s
__>function call operator. The value returned by this conversion function shall be the address of a function
__>that, when invoked, has the same effect as invoking the closure type’s function call operator.


вот бы еще побороть __stdcall
Re[5]: Лямбду в WinAPI
От: _nn_  
Дата: 28.03.11 08:00
Оценка:
Здравствуйте, ilnar, Вы писали:


I>вот бы еще побороть __stdcall



Тут две проблемы

Во первых VC2010 не компилирует этот пример.
Во вторых для преобразования в указатель на функцию придется писать обертку.


Лямбду с __stdcall создать легко:
auto p = [](int a) -> int __stdcall { return a; }

Можно даже завернуть в std::function
std::function<int(int)> px(p);
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Лямбду в WinAPI
От: баг  
Дата: 28.03.11 08:02
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Убери capture parameters [&foundHWnd, &procID], и тогда будет работать. Например:

Не будет. Нужна функция а) статическая б) stdcall. У лямбда же иное — это объект с перегруженным оператором вызова. Скрестить их можно только через переходники.
Re[3]: Лямбду в WinAPI
От: jyuyjiyuijyu  
Дата: 28.03.11 08:45
Оценка:
лямбда без capture параметров прекрасно подходит для
вызова из уже скомпиленного двоичного кода ничто
не мешает конвертнуть ее в указатель на функцию
а вот с capture параметрами сложнее надо this передавать
по всей видимости иначе как она до capture параметров
дотянется естественно не совместимо с WINAPI
если я все правильно понял
Re: Лямбду в WinAPI
От: jyuyjiyuijyu  
Дата: 28.03.11 11:32
Оценка:
еще такое бывает )))
по мотивам http://www.gamedev.ru/code/forum/?id=85183&amp;page=2
#include <windows.h>
#include <stdio.h>

typedef unsigned __int32 uint32;
typedef unsigned __int16 uint16;
typedef unsigned __int8   uint8;

#include <PshPack1.h>
struct thunk
{
  uint16 a; uint8 b; uint32 c; void* param;
  uint8 d; void* pfn; uint16 e;
  //---------------------
  uint16 aa; uint8 bb; uint32 cc; void* paramm;
  uint8 dd; void* pfnn; uint16 ee;
};
#include <PopPack.h>

template<class ArgType1>
struct objCallback1
{
    void *f;
    ArgType1 a1;
    thunk &t;
    objCallback1(void *f, ArgType1 a1):f(f),t(*new thunk)
    {
        typedef char buf[sizeof(ArgType1) <= sizeof(void*) ? 1 : 0];
        objCallback1::a1 = a1;
    }
    template<class Ret_t>
    operator Ret_t *()
    {
        return join<Ret_t>();
    }
    template<class Ret_t>
    Ret_t * join()
    {
        t.a = 0x34FF; t.b = 0x24;  t.c = 0x042444C7;  t.param = (void*)a1;
        t.d = 0xB8; t.pfn = f; t.e = 0xE0FF;
        //------------------------
        t.aa = 0x34FF; t.bb = 0x24;  t.cc = 0x042444C7;  t.paramm = (void*)&t;
        t.dd = 0xB8; t.pfnn = free_join; t.ee = 0xE0FF;
        atexit((void(*)())((char*)&t + 18));
        return (Ret_t *)&t;
    }
    /*
     testlinkage.exe!objCallback1<unsigned int>::free_join(void * mem=0x00356d00)  Line 48    C++
     msvcr90d.dll!doexit(int code=0x00000000, int quick=0x00000000, int retcaller=0x00000000)  Line 591    C
     msvcr90d.dll!exit(int code=0x00000000)  Line 412 + 0xd bytes    C
     testlinkage.exe!__tmainCRTStartup()  Line 595    C
     testlinkage.exe!mainCRTStartup()  Line 399    C
     kernel32.dll!_BaseProcessStart@4()  + 0x23 bytes    
    */
    static void __stdcall free_join(void *mem)
    {
        delete mem;
    }
};

template<class ArgType1>
objCallback1<ArgType1> Join(void *f, ArgType1 a1)
{
    return objCallback1<ArgType1>(f, a1);
}

VOID CALLBACK 
MyTimerProc(void* userdata, HWND hwnd, UINT uMsg,  UINT idEvent,  DWORD dwTime)
{
    printf("User data @ 0x%p\n", userdata );
}

int main()
{
    SetTimer(0, 0, 1000, Join(MyTimerProc, 0xdeadc0de));

    MSG msg;
    int ecx = 0;
    while(ecx++ < 3 && GetMessage(&msg, NULL, 0, 0))
        DispatchMessage(&msg);
}

можно сделать доступным от 1 и более
параметров для склейки ограничение та к кому клеим
должна быть с __stdcall соглашением
Re[2]: Лямбду в WinAPI
От: Слава Израиль  
Дата: 28.03.11 19:45
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Здравствуйте, Слава, Вы писали:


A>Убери capture parameters [&foundHWnd, &procID], и тогда будет работать. Например:

A>
A>typedef int (*func)(int);

A>int foo(func f)
A>{
A>    return f(10);
A>}

A>int main()
A>{
A>    return foo([](int a) { return 2 * a; });
A>}
A>


Не взлетело,
и так тоже

    EnumWindows([](HWND hwnd,LPARAM lParam) -> BOOL __stdcall 
    {
Спасибо за внимание
Re[3]: Лямбду в WinAPI
От: alexeiz  
Дата: 28.03.11 20:07
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте, alexeiz, Вы писали:


A>>Здравствуйте, Слава, Вы писали:


A>>Убери capture parameters [&foundHWnd, &procID], и тогда будет работать. Например:

A>>
A>>typedef int (*func)(int);

A>>int foo(func f)
A>>{
A>>    return f(10);
A>>}

A>>int main()
A>>{
A>>    return foo([](int a) { return 2 * a; });
A>>}
A>>


С>Не взлетело,

С>и так тоже

С>
С>    EnumWindows([](HWND hwnd,LPARAM lParam) -> BOOL __stdcall 
С>    {

С>


В Visual C++, вероятно, такое еще не реализовано. В G++ 4.6 всё нормально.
Re[4]: Лямбду в WinAPI
От: _nn_  
Дата: 30.03.11 09:43
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>В Visual C++, вероятно, такое еще не реализовано. В G++ 4.6 всё нормально.


В следующем релизе будет работать
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Лямбду в WinAPI
От: 23W http://kyselgov.pp.ua/
Дата: 15.12.11 11:28
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, alexeiz, Вы писали:

A>>В Visual C++, вероятно, такое еще не реализовано. В G++ 4.6 всё нормально.
__>В следующем релизе будет работать

а сейчас как быть ? может через std::bind(), std::mem_fn() или через еще что-то можно передать лямбду в качестве callback функции ?
P.S.: кстати, по стандарту лямбды не поддерживают модели вызовов. Т.е. такое []() -> BOOL __stdcall {return TRUE;} компилироваться не должно. В VC++ 2010 SP1 такой код все же компилируется, но при этом __stdcall выбрасывается, как будто бы его нет...
Re[6]: Лямбду в WinAPI
От: _NN_  
Дата: 15.12.11 12:18
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, alexeiz, Вы писали:

A>>>В Visual C++, вероятно, такое еще не реализовано. В G++ 4.6 всё нормально.
__>>В следующем релизе будет работать

23W>а сейчас как быть ? может через std::bind(), std::mem_fn() или через еще что-то можно передать лямбду в качестве callback функции ?

Сейчас использовать просто функцию.
Чем вариант плох ?

23W>P.S.: кстати, по стандарту лямбды не поддерживают модели вызовов. Т.е. такое []() -> BOOL __stdcall {return TRUE;} компилироваться не должно. В VC++ 2010 SP1 такой код все же компилируется, но при этом __stdcall выбрасывается, как будто бы его нет...

По стандарту и __stdcall не существует
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Лямбду в WinAPI
От: 23W http://kyselgov.pp.ua/
Дата: 15.12.11 12:54
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, 23W, Вы писали:


23W>>Здравствуйте, _nn_, Вы писали:


__>>>Здравствуйте, alexeiz, Вы писали:

A>>>>В Visual C++, вероятно, такое еще не реализовано. В G++ 4.6 всё нормально.
__>>>В следующем релизе будет работать

23W>>а сейчас как быть ? может через std::bind(), std::mem_fn() или через еще что-то можно передать лямбду в качестве callback функции ?

_NN>Сейчас использовать просто функцию.
_NN>Чем вариант плох ?

хотелось все и сразу

23W>>P.S.: кстати, по стандарту лямбды не поддерживают модели вызовов. Т.е. такое []() -> BOOL __stdcall {return TRUE;} компилироваться не должно. В VC++ 2010 SP1 такой код все же компилируется, но при этом __stdcall выбрасывается, как будто бы его нет...

_NN>По стандарту и __stdcall не существует
это точно но в принципе поведением VC++ 2010 я удивлен, принял модель вызова и проигнорировал ее
Re: Лямбду в WinAPI
От: Кодт Россия  
Дата: 15.12.11 13:37
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте.


С>А можно как нибудь заставить работать такое:


С>
С>HWND FindApplicationWindow()
С>{
С>    HWND foundHWnd = 0;
С>    DWORD procID = GetCurrentProcessId();
С>    EnumWindows([&foundHWnd,&procID](HWND hWnd, LPARAM lParam) -> BOOL
С>    {
С>        /*
С>         ********************************************
С>         */
С>        return TRUE;
С>    },
С>    0);
С>}
С>


Только если сделать ещё один переходник
BOOL CALLBACK enumwindows_thunk(HWND hwnd, LPARAM arg)
{
  return (*(const function<BOOL(HWND)>*)arg)(hwnd);
}

LPARAM enumwindows_arg(const function<BOOL(HWND)>& fun)
{
  return (LPARAM)&fun;
}

.......
EnumWindows(
  enumwindows_thunk,
  enumwindows_arg(
    [&foundHWnd,&procId](HWND hwnd) -> BOOL
    {
      .....
    }
  )
);
.....

Идея в том, чтобы передавать замыкание как аргумент в колбек, и уже в колбеке вызывать всё по-человечески.
Перекуём баги на фичи!
Re[2]: Лямбду в WinAPI
От: Centaur Россия  
Дата: 15.12.11 14:25
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>еще такое бывает )))

J>    template<class Ret_t>
J>    Ret_t * join()
J>    {
J>        t.a = 0x34FF; t.b = 0x24;  t.c = 0x042444C7;  t.param = (void*)a1;
J>        t.d = 0xB8; t.pfn = f; t.e = 0xE0FF;
J>        //------------------------
J>        t.aa = 0x34FF; t.bb = 0x24;  t.cc = 0x042444C7;  t.paramm = (void*)&t;
J>        t.dd = 0xB8; t.pfnn = free_join; t.ee = 0xE0FF;
J>        atexit((void(*)())((char*)&t + 18));
J>        return (Ret_t *)&t;
J>    }

:maniac: Убивать. Это развалится при первой же попытке скомпилировать и запустить на любой другой платформе. Начиная с x64.
Re[2]: Лямбду в WinAPI
От: 23W http://kyselgov.pp.ua/
Дата: 16.12.11 10:54
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Слава, Вы писали:


С>>Здравствуйте.


С>>А можно как нибудь заставить работать такое:


С>>
С>>HWND FindApplicationWindow()
С>>{
С>>    HWND foundHWnd = 0;
С>>    DWORD procID = GetCurrentProcessId();
С>>    EnumWindows([&foundHWnd,&procID](HWND hWnd, LPARAM lParam) -> BOOL
С>>    {
С>>        /*
С>>         ********************************************
С>>         */
С>>        return TRUE;
С>>    },
С>>    0);
С>>}
С>>


К>Только если сделать ещё один переходник

К>
К>BOOL CALLBACK enumwindows_thunk(HWND hwnd, LPARAM arg)
К>{
К>  return (*(const function<BOOL(HWND)>*)arg)(hwnd);
К>}

К>LPARAM enumwindows_arg(const function<BOOL(HWND)>& fun)
К>{
К>  return (LPARAM)&fun;
К>}

К>.......
К>EnumWindows(
К>  enumwindows_thunk,
К>  enumwindows_arg(
К>    [&foundHWnd,&procId](HWND hwnd) -> BOOL
К>    {
К>      .....
К>    }
К>  )
К>);
К>.....
К>

К>Идея в том, чтобы передавать замыкание как аргумент в колбек, и уже в колбеке вызывать всё по-человечески.


Эта идей не работает, т.к. все калбеки имеют разный список параметров... что писать под каждый из них enumwindows_thunk ? толку тогда от лябды... ведь основная идея была уйти от статических функций в своем коде.
Шаблоном к сожалению тут тоже не помочь. Можно сделать шаблоную ф-ю с форматом вызова __stdcall которая бы вызывала экивиалентную ей по списку параметров лямбду, но как эту лямбду передать в шаблон ?
Re: Лямбду в WinAPI
От: 0xDEADBEEF Ниоткуда  
Дата: 16.12.11 11:24
Оценка:
Здравствуйте, Слава, Вы писали:

С>Здравствуйте.


С>А можно как нибудь заставить работать такое:

Напрямую — нет.
Причины:
— коллбеки Win32Api имеют соглашение вызова stdcall, а сишные функции — cdecl
— твоя лямбда захватывает переменные. Такая лямбда не может быть приведена к типу "указатель на функцию".

А вот так — работает (GCC-4.6, MSVC-10), причем без всяких извращений с std::function
//CC G++
//G++-FLAGS -Xdebug -O0 -std=gnu++0x -- -lstdc++
#include <windows.h>
#include <iostream>
#include <string>

template<class LAMBDA>
BOOL CALLBACK EnumWindowsLambda(HWND hwnd, LPARAM lParam)
{
    return (*reinterpret_cast<LAMBDA*>(lParam))(hwnd);
}

template<class LAMBDA>
BOOL EnumWindows(LAMBDA lpEnumLambda)
{
    return EnumWindows(&EnumWindowsLambda<LAMBDA>, reinterpret_cast<LPARAM>(&lpEnumLambda));
}

int main()
{
    std::string title = "HWND:";
    EnumWindows([&](HWND hwnd) -> BOOL {
        std::cout << title << std::hex << hwnd << std::endl;
        return TRUE;
    });
}
__________
16.There is no cause so right that one cannot find a fool following it.
Re[2]: Лямбду в WinAPI
От: 0xDEADBEEF Ниоткуда  
Дата: 16.12.11 12:23
Оценка: 13 (1)
Здравствуйте, 0xDEADBEEF, Вы писали:

Версия №2 — принимает только лямбды с нужным набором параметров. Причем эти параметры описаны в определении функции.
И, заодно убрана лишняя функция из глобального скопа.
BOOL EnumWindows(std::function<BOOL(HWND)> const& cb)
{
    typedef std::function<BOOL(HWND)> cbtype;
    struct cbwrap {
        static BOOL CALLBACK cb(HWND hwnd, LPARAM lParam)
        {
            return (*reinterpret_cast<cbtype*>(lParam))(hwnd);
        }
    };
    return EnumWindows(&cbwrap::cb, reinterpret_cast<LPARAM>(&cb));
}

int main()
{
    std::string title = "HWND:";
        //это сработает, тк. параметры лямбды полностью совпадают
    EnumWindows([&](HWND hwnd) -> BOOL {
        std::cout << title << std::hex << hwnd << std::endl;
        return TRUE;
    });
        //это не сработает, тк. параметры лямбды не совпадают
    EnumWindows([&](HWND hwnd) -> std::string {
        return "aaaa";
    });
}
__________
16.There is no cause so right that one cannot find a fool following it.
Re[3]: Лямбду в WinAPI
От: Кодт Россия  
Дата: 16.12.11 14:15
Оценка:
Здравствуйте, 23W, Вы писали:

23W>Эта идей не работает, т.к. все калбеки имеют разный список параметров... что писать под каждый из них enumwindows_thunk ? толку тогда от лябды... ведь основная идея была уйти от статических функций в своем коде.


Если есть более чем одно замыкание-колбек для EnumWindow, то идея работает. Без этого пришлось бы заводить структуру для передачи данных из контекста.
Что-то такое
void foo()
{
  ...
  struct args
  {
    HWND& found; DWORD procid;
    static BOOL CALLBACK ewp(HWND w, LPARAM p) { return (*(args*)p)->ewp(w); }
    BOOL ewp() { ..... }
  } a;
  EnumWindows(args::ewp, &a);
  ...
}

Ну не мрак ли?

23W>Шаблоном к сожалению тут тоже не помочь. Можно сделать шаблоную ф-ю с форматом вызова __stdcall которая бы вызывала экивиалентную ей по списку параметров лямбду, но как эту лямбду передать в шаблон ?


А примерно так
template<class CB> struct callback;

template<class F> struct callback_base
{
  typedef function<F> closure_type;
  static LPARAM param(closure_type const& f) { return (LPARAM)&f; }
};

template<class R> struct callback<R (CALLBACK*)(LPARAM)> : callback_base<R(LPARAM)>
{
  static R CALLBACK thunk(LPARAM p) { return (*(closure_type*)p)(); }
};
template<class R, class A1> struct callback<R (CALLBACK*)(A1, LPARAM)> : callback_base<R(A1,LPARAM)>
{
  static R CALLBACK thunk(A1 a1, LPARAM p) { return (*(closure_type*)p)(a1); }
};
template<class R, class A1, class A2> struct callback<R (CALLBACK*)(A1, A2, LPARAM)> : callback_base<R(A1,A2,LPARAM)>
{
  static R CALLBACK thunk(A1 a1, A2 a2, LPARAM p) { return (*(closure_type*)p)(a1,a2); }
};
.....

.....
  EnumWindow(
    callback<ENUMWINDOWPROC>::thunk,
    callback<ENUMWINDOWPROC>::param( [](HWND)->BOOL { ..... } )
  );
.....
Перекуём баги на фичи!
Re[4]: Лямбду в WinAPI
От: 23W http://kyselgov.pp.ua/
Дата: 16.12.11 14:23
Оценка:
Здравствуйте, Кодт, Вы писали:

23W>>Шаблоном к сожалению тут тоже не помочь. Можно сделать шаблоную ф-ю с форматом вызова __stdcall которая бы вызывала экивиалентную ей по списку параметров лямбду, но как эту лямбду передать в шаблон ?


К>А примерно так

К>
К>template<class CB> struct callback;

К>template<class F> struct callback_base
К>{
К>  typedef function<F> closure_type;
К>  static LPARAM param(closure_type const& f) { return (LPARAM)&f; }
К>};

К>template<class R> struct callback<R (CALLBACK*)(LPARAM)> : callback_base<R(LPARAM)>
К>{
К>  static R CALLBACK thunk(LPARAM p) { return (*(closure_type*)p)(); }
К>};
К>template<class R, class A1> struct callback<R (CALLBACK*)(A1, LPARAM)> : callback_base<R(A1,LPARAM)>
К>{
К>  static R CALLBACK thunk(A1 a1, LPARAM p) { return (*(closure_type*)p)(a1); }
К>};
К>template<class R, class A1, class A2> struct callback<R (CALLBACK*)(A1, A2, LPARAM)> : callback_base<R(A1,A2,LPARAM)>
К>{
К>  static R CALLBACK thunk(A1 a1, A2 a2, LPARAM p) { return (*(closure_type*)p)(a1,a2); }
К>};
К>.....

К>.....
К>  EnumWindow(
К>    callback<ENUMWINDOWPROC>::thunk,
К>    callback<ENUMWINDOWPROC>::param( [](HWND)->BOOL { ..... } )
К>  );
К>.....
К>


а это уже что-то... идея красивая. спасибо — попробую.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.