util.smartptr.shared.const / 9 em C ++ 11:
Efeitos: constrói um objeto shared_ptr que possui o objeto pe deleter d. O segundo e o quarto construtores devem usar uma cópia de a para alocar memória para uso interno.
O segundo e o quarto construtores têm estes protótipos:
template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
template<class D, class A> shared_ptr(nullptr_t p, D d, A a);
No rascunho mais recente, util.smartptr.shared.const / 10 é equivalente para nosso propósito:
Efeitos: constrói um objeto shared_ptr que possui o objeto pe deleter d. Quando T não é um tipo de matriz, o primeiro e o segundo construtores ativam shared_from_this com p. O segundo e o quarto construtores devem usar uma cópia de a para alocar memória para uso interno. Se uma exceção for lançada, d (p) será chamado.
Portanto, o alocador é usado se houver necessidade de alocá-lo na memória alocada. Com base no padrão atual e nos relatórios de defeitos relevantes, a alocação não é obrigatória, mas assumida pelo comitê.
Embora a interface de shared_ptr
permita uma implementação em que nunca haja um bloco de controle e tudo shared_ptr
e weak_ptr
seja colocada em uma lista vinculada, não existe tal implementação na prática. Além disso, o texto foi modificado assumindo, por exemplo, que ele use_count
é compartilhado.
O deleter é necessário para mover apenas construtível. Portanto, não é possível ter várias cópias no shared_ptr
.
Pode-se imaginar uma implementação que coloque o deleter em um projeto especialmente projetado shared_ptr
e o mova quando o especial shared_ptr
for excluído. Embora a implementação pareça estar em conformidade, também é estranha, especialmente porque um bloco de controle pode ser necessário para a contagem de uso (talvez seja possível, mas ainda mais estranho, fazer a mesma coisa com a contagem de uso).
DRs relevantes que encontrei: 545 , 575 , 2434 (que reconhecem que todas as implementações estão usando um bloco de controle e parecem implicar que restrições de multi-threading o exigem de alguma forma), 2802 (que exige que o deleter se mova apenas construtível e, portanto, impeça a implementação onde o deleter é copiado entre vários shared_ptr
).