Estou criando esse tópico para me informar mais sobre o especificador noexcept da linguagem C++, ontem acabei o conhecendo por acidente numa pesquisa relacionada a throw que caiu numa página do MSDN, que tinha essa informação:
Exception specifications are a C++ language feature that is deprecated in C++11. They were designed to provide summary information about what exceptions can be thrown out of a function, but in practice they were found to be problematic. The one exception specification that did prove to be somewhat useful was the throw() specification. For example:
void MyFunction(int i) throw();
tells the compiler that the function does not throw any exceptions. It is the equivalent to using __declspec(nothrow). Its use is considered optional.
(C++11) In the ISO C++11 Standard, noexcept operator was introduced and is supported in Visual Studio 2015 and later. Whenever possible, use noexcept to specify whether a function might throw exceptions.
Na hora veio o susto: "Exception specifications are a C++ language feature that is deprecated in C++11". Pensei até que fosse algum tipo movimento para abolir exceptions de vez, onde não seria mais possível tratar e lançar exceptions, porém depois de alguns pesquisas pelo o que eu entendi ele vem como otimização para substituir a especificação de exceptions.
Agora para dizer que um método/função pode lançar uma exceção com noexcept:
int main()
{
std::string resultado[] = {"falso", "verdadeiro"};
Teste teste;
std::cout << "metodoA tem noexcept: " << resultado[noexcept(teste.metodoA())] << std::endl;
std::cout << "metodoB tem noexcept: " << resultado[noexcept(teste.metodoB())] << std::endl;
std::cout << "metodoC tem noexcept: " << resultado[noexcept(teste.metodoC())] << std::endl;
std::cout << "metodoD tem noexcept: " << resultado[noexcept(teste.metodoD())] << std::endl;
std::cout << "metodoE tem noexcept: " << resultado[noexcept(teste.metodoE())] << std::endl;
std::cout << "metodoF tem noexcept: " << resultado[noexcept(teste.metodoF())] << std::endl;
}
Resultado da execução:
metodoA tem noexcept: falso
metodoB tem noexcept: verdadeiro
metodoC tem noexcept: falso
metodoD tem noexcept: verdadeiro
metodoE tem noexcept: verdadeiro
metodoF tem noexcept: falso
É isso mesmo? Está tudo certo?
Posso continuar lançando e tratando exceções me preocupando apenas agora em alterar o especificador para "noexcept (false)" no caso em que pode ocorrer lançamento e apenas "noexcept" ou "noexcept (true)" para o caso em que não são lançadas exceções?