[C++11 e posterior] Dúvidas sobre uso do especificador noexcept, substituto do throw

1. [C++11 e posterior] Dúvidas sobre uso do especificador noexcept, substituto do throw

M.
XProtoman

(usa Fedora)

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:
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.

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


É 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.


  






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts