Enviado em 15/01/2016 - 07:45h
Bom dia a todos,
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:
Agora para dizer que um método/função pode lançar uma exceção com noexcept:
Para dizer o caso de não:
Existem outras formas usando throw que abordei no código abaixo, não coloquei aqui por causa do especificador estar obsoleto.
Segue um exemplo de código que produzi que testa o noexcept utilizando o operador noexcept:
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?
Obrigado.
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:
https://msdn.microsoft.com/en-us/library/wfa0edys.aspx
Exception Specifications (throw) (C++)
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.Exception Specifications (throw) (C++)
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.
Agora para dizer que um método/função pode lançar uma exceção com noexcept:
void metodoA();
void metodoC() noexcept (false);
Para dizer o caso de não:
void metodoB() noexcept;
void metodoD() noexcept (true);
Existem outras formas usando throw que abordei no código abaixo, não coloquei aqui por causa do especificador estar obsoleto.
Segue um exemplo de código que produzi que testa o noexcept utilizando o operador noexcept:
// Salve esse arquivo como noexcept.cpp
// Compile com: g++ -std=c++11 -pedantic-errors -Wall -Wextra -Werror noexcept.cpp -o noexcept.run
// Rode com ./noexcept.run
#include <iostream>
#include <stdexcept>
class Teste
{
public:
void metodoA()
{
}
void metodoB() noexcept
{
}
void metodoC() noexcept (false)
{
}
void metodoD() noexcept (true)
{
}
void metodoE() throw ()
{
}
void metodoF() throw (std::exception)
{
}
};
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
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?
Obrigado.