Eu estou tentando construir um std::thread
com uma função de membro que não leva argumentos e retornos void
. Não consigo descobrir nenhuma sintaxe que funcione - o compilador reclama, não importa o quê. Qual é a maneira correta de implementar spawn()
para que ele retorne um std::thread
que seja executado test()
?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
c++
multithreading
c++11
abergmeier
fonte
fonte
std::move( std::thread(func) );
é melhor, poisstd::thread
não tem um construtor de cópias.std::move
neste caso é redundante - se isso não fosse verdade e não houvesse construtor de cópias, o compilador apresentaria um erro de qualquer maneira.Respostas:
EDIT: contabilizando sua edição, você deve fazer assim:
ATUALIZAÇÃO: Quero explicar mais alguns pontos, alguns deles também foram discutidos nos comentários.
A sintaxe descrita acima é definida em termos da definição INVOKE (§20.8.2.1):
Outro fato geral que quero destacar é que, por padrão, o construtor de threads copia todos os argumentos passados para ele. A razão para isso é que os argumentos podem precisar sobreviver ao segmento de chamada, copiar os argumentos garante isso. Em vez disso, se você quiser realmente passar uma referência, poderá usar um
std::reference_wrapper
criado porstd::ref
.Ao fazer isso, você promete que garantirá que os argumentos ainda existam quando o encadeamento operar neles.
Observe que todas as coisas mencionadas acima também podem ser aplicadas a
std::async
estd::bind
.fonte
std::thread
construtor funciona como se os argumentos fossem passados parastd::bind
. Para chamar uma função de membro, o primeiro argumentostd::bind
deve ser um ponteiro, referência ou ponteiro compartilhado para um objeto do tipo apropriado.bind
? Não consigo encontrar isso em lugar nenhum.Como você está usando o C ++ 11, a expressão lambda é uma solução agradável e limpa.
como
this->
pode ser omitido, pode ser reduzido para:ou apenas
fonte
std::move
ao retornar uma variável local por valor. Isso realmente inibe o RVO. Se você apenas retornar por valor (sem a movimentação), o compilador poderá usar o RVO, e se isso não acontecer, o padrão diz que ele deve chamar a semântica da movimentação.[=]
. Com isso, você pode copiar inadvertidamente um objeto enorme. Em geral, é um cheiro de código para usar[&]
ou[=]
.[&]
), você pode introduzir bugs, como algumas referências pendentes. (Por exemplo,std::thread spawn() { int i = 10; return std::thread( [&] { std::cout<<i<<"\n"; } ); }
)Aqui está um exemplo completo
Compilar com g ++ produz o seguinte resultado
fonte
delete
da memória da pilha :)O @ hop5 e o @RnMss sugeriram o uso de lambdas C ++ 11, mas se você lida com ponteiros, pode usá-los diretamente:
saídas
A amostra reescrita desta resposta seria então:
fonte
Alguns usuários já deram sua resposta e a explicaram muito bem.
Gostaria de adicionar mais algumas coisas relacionadas ao segmento.
Como trabalhar com functor e thread. Por favor, consulte o exemplo abaixo.
O thread fará sua própria cópia do objeto ao passar o objeto.
Outra maneira de conseguir a mesma coisa é:
Mas se você deseja passar o objeto por referência, use a sintaxe abaixo:
fonte