Pergunta

Atualmente estou aprendendo sobre simultaneidade em C++ e me deparei com o uso de um vetor de threads, o que acredito que será possível em C++0x.No entanto, meu compilador atual não parece ter uma implementação de contêineres com reconhecimento de movimentação e, portanto, recebo erros gerados porque std::thread::thread(const std::thread&) é excluído, ou seja, só posso usar o construtor de movimento/atribuição de movimento com std::thread.

Estou correto ao pensar que poderia contornar esse problema escrevendo um alocador personalizado usando

void MyAllocator::construct (pointer p, reference val)
/* should be non-const reference to val because using move constructor? */
{
    new ((void*)p) T (std::move(val));
}

em vez de

void allocator::construct (pointer p, const_reference val)
{
    new ((void*)p) T (val);
}

?Ou alguma outra variação deste tema (possivelmente usando uma sobrecarga de MyAllocator::construct).

Observação:O objetivo principal é ser um exercício educacional de curto prazo e um trabalho de desempenho suficientemente bom para brincar com threads em contêineres.eu só usaria MyAllocator nesse contexto.No entanto, por favor, indique-me também quaisquer bibliotecas que possam ter isso implementado para que eu possa dar uma olhada no código-fonte.

Foi útil?

Solução

Se o seu compilador não fornecer uma consciência de movimento std::vector Então você terá que escrever sua própria especialização de std::vector<std::thread> em vez de apenas fornecer um alocador personalizado. Todo o C ++ 03 vector A interface depende da cópia: push_back() copia elementos em; resize() inicializa os elementos vazios com um cópia de do elemento aprovado como o segundo parâmetro (mesmo que esse seja o valor padrão de T()); resize(), reserve(), insert(), erase() e push_back() vai cópia de elementos se o vetor precisar de realocação, ou elementos precisarão se mover e assim por diante.

Este é um problema tão comum que incluí essa especialização com o meu (comercial) apenas :: thread implementação de std::thread.

Outras dicas

A maneira mais fácil de contornar o problema seria alocar os fios na pilha e manipular ponteiros para eles.

Verifica a Boost Pointer Container biblioteca: boost::ptr_vector<std::thread> Parece -me o que você está procurando.

O requisito de que os contêineres std aceitem apenas objetos copiáveis ​​tem mais a ver com as interfaces do contêiner C++ 03 do que com a implementação do alocador.Por exemplo

vector<T> b(100);
vector<T> a;
a=b;
assert(a==b);

O padrão nos garante que a==b é verdadeiro.No entanto, se T não fosse copiável, então, na melhor das hipóteses, a=b não será compilado; na pior, a=b será indefinido.Além disso,

a.push_back(T());

pode fazer com que um novo espaço seja alocado e, nos bastidores, cópias do antigo sejam feitas para o novo armazenamento subjacente.

Além disso, não há nada no padrão C++03 que diga que uma implementação realmente precisa chamar allocator.construct e, de fato, muitos (gcc, por exemplo) não o fazem.

O padrão C++0x adiciona novas funções de membro à interface do contêiner para tipos móveis e esclarece como coisas como operator= se comportam em sua presença.

Consulte www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2486.pdf

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top