Existe alguma diferença entre throw()
e noexcept
diferente de ser verificado em tempo de execução e tempo de compilação, respectivamente?
Este artigo da Wikipedia C ++ 11 sugere que os especificadores de lançamento do C ++ 03 estão obsoletos.
Por que então, é noexcept
capaz de cobrir tudo isso em tempo de compilação?
[Observação: verifiquei esta pergunta e este artigo , mas não consegui determinar o motivo sólido para a suspensão de uso.]
noexcept
podem ocorrer verificações de tempo de execução. A principal diferença entre eles é que a quebranoexcept
causastd::terminate
enquanto a quebrathrow
causastd::unexpected
. Também um comportamento de desenrolamento de pilha ligeiramente diferente nesses casos.Respostas:
Os especificadores de exceção foram descontinuados porque os especificadores de exceção geralmente são uma péssima ideia .
noexcept
foi adicionado porque é o único uso razoavelmente útil de um especificador de exceção: saber quando uma função não lançará uma exceção. Assim, torna-se uma escolha binária: funções que vão lançar e funções que não vão lançar.noexcept
foi adicionado em vez de apenas remover todos os especificadores de lançamento, excetothrow()
porquenoexcept
é mais poderoso.noexcept
pode ter um parâmetro que em tempo de compilação se transforma em um booleano. Se o booleano for verdadeiro, o valor permanecenoexcept
. Se o booleano for falso, onoexcept
não pega e a função pode ser lançada.Assim, você pode fazer algo assim:
Faz
CreateOtherClass
exceções lance? Pode, seT
o construtor padrão puder. Como podemos saber? Como isso:Assim,
CreateOtherClass()
irá lançar iff o construtor padrão de determinado tipo lançar. Isso corrige um dos principais problemas com especificadores de exceção: sua incapacidade de propagar a pilha de chamadas.Você não pode fazer isso com
throw()
.fonte
noexcept
. Eu nunca usei othrow()
especificador, nunca e estou tentando determinar senoexcept
realmente fornece algum benefício (além da documentação verificada pelo compilador).std::terminate
. o que é MUITO PIOR ! o código pode entrar furtivamente em versões que têm funções marcadasnoexcept
e violações em tempo de execução (ou seja, em sites de clientes) são detectadas. Eu quis dizer que o compilador garante a geração de código que não lança exceções em primeiro lugar.throws()
, se uma exceção for lançada, a pilha deve ser desfeita até o escopo dessa função (para que todas as variáveis automáticas na função sejam destruídas) em que pontoterminate()
é chamado (viaunexpected()
). Se uma função for marcadanoexcept
, se uma exceção for lançada, terminate será chamado (o desenrolamento da pilha é um detalhe definido pela implementação).noexcept
não é verificado em tempo de compilação.Quando uma função que é declarada
noexcept
outhrow()
tenta lançar uma exceção, a única diferença é que uma chamaterminate
e as outras chamadasunexpected
e o último estilo de tratamento de exceção foi efetivamente descontinuado.fonte
throw()
/noexcept
, a verificação do tempo de compilação garante que um overrider também tenha.std::unexpected()
é chamado pelo tempo de execução C ++ quando uma especificação de exceção dinâmica é violada: uma exceção é lançada de uma função cuja especificação de exceção proíbe exceções desse tipo.std::unexpected()
também pode ser chamado diretamente do programa.Em ambos os casos,
std::unexpected
chama o atualmente instaladostd::unexpected_handler
. Asstd::unexpected_handler
chamadas padrãostd::terminate
.fonte