// error handling could be improved too
template <typename T>
using ToPointer = typename std::add_pointer<typename std::remove_reference<Fun>::type>::type;
template <typename Fun>
BOOL CALLBACK AdaptEnumWindowsProc(HWND hwnd, LPARAM lParam) {
Fun& fun = *reinterpret_cast<ToPointer<Fun>>(lparam); // what's the correct cast?
return fun(hwnd);
}
template <typename Fun>
BOOL BetterEnumWindows(Fun&& fun) {
return ::EnumWindows(&AdaptEnumWindowsProc<Fun>, reinterpret_cast<LPARAM>(&fun));
}
Ly8gZXJyb3IgaGFuZGxpbmcgY291bGQgYmUgaW1wcm92ZWQgdG9vCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KdXNpbmcgVG9Qb2ludGVyID0gdHlwZW5hbWUgc3RkOjphZGRfcG9pbnRlcjx0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8RnVuPjo6dHlwZT46OnR5cGU7Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRnVuPgpCT09MIENBTExCQUNLIEFkYXB0RW51bVdpbmRvd3NQcm9jKEhXTkQgaHduZCwgTFBBUkFNIGxQYXJhbSkgewogICAgRnVuJiBmdW4gPSAqcmVpbnRlcnByZXRfY2FzdDxUb1BvaW50ZXI8RnVuPj4obHBhcmFtKTsgLy8gd2hhdCdzIHRoZSBjb3JyZWN0IGNhc3Q/CiAgICByZXR1cm4gZnVuKGh3bmQpOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRnVuPgpCT09MIEJldHRlckVudW1XaW5kb3dzKEZ1biYmIGZ1bikgewogICAgcmV0dXJuIDo6RW51bVdpbmRvd3MoJkFkYXB0RW51bVdpbmRvd3NQcm9jPEZ1bj4sIHJlaW50ZXJwcmV0X2Nhc3Q8TFBBUkFNPigmZnVuKSk7Cn0KCg==