Я пытаюсь создать std::thread
с помощью функции-члена, которая не принимает аргументов и возвращает void
. Я не могу понять, какой синтаксис работает - компилятор жалуется, несмотря ни на что. Как правильно реализовать, spawn()
чтобы он возвращал std::thread
выполняемое test()
?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
c++
multithreading
c++11
abergmeier
источник
источник
std::move( std::thread(func) );
лучше, такstd::thread
как не имеет конструктора копирования.std::move
избыточность в этом случае - если бы это было не так, и не было конструктора копирования, компилятор все равно выдал бы ошибку.Ответы:
РЕДАКТИРОВАТЬ: Учитывая ваши изменения, вы должны сделать это так:
ОБНОВЛЕНИЕ: Я хочу объяснить еще некоторые моменты, некоторые из них также обсуждались в комментариях.
Описанный выше синтаксис определен в терминах определения INVOKE (§20.8.2.1):
Еще один общий факт, на который я хочу обратить внимание, заключается в том, что по умолчанию конструктор потока будет копировать все передаваемые ему аргументы. Причина этого в том, что аргументам может понадобиться пережить вызывающий поток, копирование аргументов гарантирует это. Вместо этого, если вы хотите действительно передать ссылку, вы можете использовать
std::reference_wrapper
созданныйstd::ref
.Делая это, вы обещаете, что позаботитесь о том, чтобы аргументы все еще существовали, когда поток обрабатывает их.
Обратите внимание, что все вещи, упомянутые выше, также могут быть применены к
std::async
иstd::bind
.источник
std::thread
конструктора с несколькими аргументами работает так, как если бы аргументы были переданыstd::bind
. Для вызова функции-члена первым аргументомstd::bind
должен быть указатель, ссылка или общий указатель на объект соответствующего типа.bind
? Я не могу найти это нигде.Поскольку вы используете C ++ 11, лямбда-выражение является хорошим и чистым решением.
так как
this->
может быть опущено, оно может быть сокращено до:или просто
источник
std::move
при возврате локальной переменной по значению. Это на самом деле тормозит RVO. Если вы просто возвращаете по значению (без перемещения), компилятор может использовать RVO, а если нет, стандарт говорит, что он должен вызывать семантику перемещения.[=]
. При этом вы можете случайно скопировать огромный объект. В общем, это кодовый запах для использования[&]
или[=]
.[&]
), вы можете вводить ошибки, например, висячие ссылки. (Например,std::thread spawn() { int i = 10; return std::thread( [&] { std::cout<<i<<"\n"; } ); }
)Вот полный пример
Компиляция с g ++ дает следующий результат
источник
delete
на память из кучи :)@ hop5 и @RnMss предложили использовать лямбды C ++ 11, но если вы имеете дело с указателями, вы можете использовать их напрямую:
выходы
Переписанный образец из этого ответа будет тогда:
источник
Некоторые пользователи уже дали свой ответ и объяснили это очень хорошо.
Я хотел бы добавить еще несколько вещей, связанных с темой.
Как работать с функтором и потоком. Пожалуйста, обратитесь к примеру ниже.
Поток создаст свою собственную копию объекта при передаче объекта.
Еще один способ достичь того же:
Но если вы хотите передать объект по ссылке, используйте следующий синтаксис:
источник