Para entender o enum
, comece considerando o destruidor sem ele:
~scoped_ptr() {
delete ptr_;
}
onde ptr_
está um C*
. Se o tipo C
estiver incompleto neste ponto, isto é, tudo o que o compilador sabe é struct C;
, então (1) um destruidor de não fazer nada gerado por padrão é usado para a instância C apontada. É improvável que seja a coisa certa a se fazer para um objeto gerenciado por um ponteiro inteligente.
Se a exclusão por meio de um ponteiro para o tipo incompleto sempre teve comportamento indefinido, o padrão pode apenas exigir que o compilador o diagnostique e falhe. Mas fica bem definido quando o destruidor real é trivial: conhecimento que o programador pode ter, mas o compilador não. Por que a linguagem define e permite isso está além de mim, mas C ++ suporta muitas práticas que hoje não são consideradas melhores práticas.
Um tipo completo tem um tamanho conhecido e, portanto, sizeof(C)
irá compilar se e somente se C
for um tipo completo - com destruidor conhecido. Portanto, ele pode ser usado como um guarda. Uma maneira seria simplesmente
(void) sizeof(C);
Eu acho que com algum compilador e opções, o compilador o otimiza antes que ele perceba que não deve ser compilado e que enum
é uma maneira de evitar esse comportamento não-conforme do compilador:
enum { type_must_be_complete = sizeof(C) };
Uma explicação alternativa para a escolha, em enum
vez de apenas uma expressão descartada, é simplesmente preferência pessoal.
Ou, como sugere James T. Hugget em um comentário a esta resposta, “O enum pode ser uma forma de criar uma mensagem de erro pseudo-portátil em tempo de compilação”.
(1) O destruidor de não fazer nada gerado por padrão para um tipo incompleto era um problema com o antigo std::auto_ptr
. Foi tão insidioso que chegou a um item do GOTW sobre o idioma PIMPL , escrito pelo presidente do comitê internacional de padronização C ++ Herb Sutter. Claro, hoje em dia isso std::auto_ptr
está obsoleto, em vez disso, usaremos algum outro mecanismo.
ptr_
si mesmo nosizeof
como emsizeof(*ptr_)
vez desizeof(C)
.