Был другой способ, когда лямбды не были стандартом - вы могли определить локальный класс функции и определить внутреннюю функцию в этом классе. Что-то вроде:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(LPVOID param)
{
/// do the action
return 0;
}
};
::CreateThread(0, 0,
&message_box::display,
0, 0, 0);
}
Теперь давайте рассмотрим ваш вопрос. Вы хотели передать текст сообщения в std :: string в STL. Поскольку он занимает динамическую память, которая может быть освобождена вашим начальным потоком, новый поток, работающий параллельно, должен иметь гарантию, что текст сообщения все еще будет доступен для него. Это можно сделать, скопировав (что будет работать с лямбда-захватом по значению - [=] вводчик) или разделив ссылку (через подсчет ссылок, скажем так). Давайте рассмотрим копирование:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(void *param)
{
MessageBox(0, ((string *)param)->c_str(), "Message", 0);
delete (string *)param;
return 0;
}
};
string *clone = new string(message);
::CreateThread(0, 0,
&message_box::display,
clone, 0, 0);
}
Обратите внимание, что копия размещается в исходном потоке и уничтожается в новом. Для этого требуется поддержка многопоточности вашей CRT.
В случае, если новый поток не запускается, вы в конечном итоге потеряли память. Давайте исправим это:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(void *param)
{
auto_ptr<string> message((string *)param);
MessageBox(0, message->c_str(), "Message", 0);
return 0;
}
};
auto_ptr<string> clone(new string(message));
if (::CreateThread(0, 0, &message_box::display, clone.get(), 0, 0))
clone.release(); // release only if the new thread starts successfully.
}
Поскольку память управляется CRT, CRT необходимо инициализировать в новом потоке, что не выполняется API CreateThread. Вместо этого вы должны использовать CRT beginthread / beginthreadex:
void msg(const string &message)
{
struct message_box
{
static unsigned int WINAPI display(void *param)
{
auto_ptr<string> message((string *)param);
MessageBox(0, message->c_str(), "Message", 0);
return 0;
}
};
auto_ptr<string> clone(new string(message));
if (_beginthreadex(0, 0, &message_box::display, clone.get(), 0, 0))
clone.release(); // release only if the new thread starts successfully.
}
Это решение оставляет в стороне проблему утечки самого потока как ресурса. Но я думаю, что вы можете найти другие сообщения для этого на stackoverflow.com:)
спасибо)