2011-03-29 17 views
6

Estoy tratando de definir una clase de excepción realmente simple. Debido a que es tan simple, quiero mantenerlo solo en el archivo .h, pero al compilador no le gusta throw(). El código:Método Inline throw() en C++

#include <exception> 
#include <string> 

class PricingException : public virtual std::exception 
{ 
private: 
    std::string msg; 
public: 
     PricingException(std::string message) : msg(message) {} 
     const char* what() const throw() { return msg.c_str(); } 
     ~PricingException() throw() {} 
}; 

GCC da los siguientes errores:

/home/ga/dev/CppGroup/MonteCarlo/PricingException.h:13: error: expected unqualified-id before ‘{’ token 
/home/ga/dev/CppGroup/MonteCarlo/PricingException.h:14: error: expected unqualified-id before ‘{’ token 

para líneas con throw(). ¿Alguna de idea de cómo arreglarlo?

EDITAR

Me trataron de retirar los cuerpos de los métodos problemáticos, es decir

virtual ~PricingException() throw();// {} 

Y ahora me sale el mensaje de error aún más raro:

/home/ga/dev/CppGroup/MonteCarlo/PricingException.h:14: error: looser throw specifier for ‘virtual PricingException::~PricingException()’ 
/usr/include/c++/4.5/exception:65: error: overriding ‘virtual std::exception::~exception() throw()’ 

Es simplemente ignorado mi especificador de tiro!

+0

compila bien aquí con gcc versión 4.2.1 (Apple Inc. compilación 5664) – Thomas

+0

Estoy ejecutando 'gcc (Debian 4.5.2-4) 4.5.2' – Grzenio

+0

' #include '? '#include '? –

Respuesta

0

¡Lo encontré finalmente! @Mike Seymour tenía razón en su comentario: resulta que en un archivo nr3.h (parte del código Numerical Recepies) hay una macro throw(message) definida.

Lo que no entiendo es por qué impactos compilación de archivos que no incluyen este archivo .h ...

De todos modos, creo que Visual Studio tenía una orden de compilación diferente o algo así, por lo que era pura suerte que compiló allí y no bajo gcc.

3

El más cercano que he encontrado en el C++ 0x es:

15.4 especificaciones de excepción [except.spec]

2 Una excepción-especificación deben aparecer sólo en una declarador función para un tipo de función, un puntero al tipo de función, una referencia al tipo de función o un puntero al tipo de función miembro que es el tipo de nivel superior de una declaración o definición, o en un tipo que aparece como un parámetro o tipo de retorno en un declarador de función.

Me parece que podría no permitir el uso de especificaciones de excepción en las definiciones.

+0

Cada definición es una declaración, ¿no? –

+0

Incluso el párrafo citado dice "o definición". –

+0

@Charles: Lo asociaría con lo que viene antes: "o apunta al tipo de función de miembro que es el tipo de nivel superior de una declaración o definición" porque va seguido de una coma y otro miembro de la alternativa. –

0

¿Has probado throw sin la()? en este ejemplo (sé que es en el archivo .cpp) pero veo que la lanza no todos tienen un paréntesis

http://www.glenmccl.com/eh_cmp.htm

+0

¿Dónde? En la parte inferior de la página dicen 'uno con: throw() no se permite lanzar excepciones. – Grzenio

+2

Estas son especificaciones de excepción, no arrojan expresiones, y necesitan los paréntesis. –

1

yo no era capaz de reproducir esto en varias versiones de g ++. El problema más probable es que un archivo de encabezado incluido previamente tenga un problema que finalmente está causando problemas al compilador cuando ve el throw pero no antes.

4

Pruebe la sintaxis de C++ 0x en su lugar, g ++ 4.5 puede ser lo suficientemente reciente para apoyarlo:

const char* what() const noexcept { return msg.c_str(); } 

Sin embargo, esto no debería importar (redacción del proyecto de 3242, la sección [except.spec]:

Dos excepción especificaciones son compatibles si:

  • ambos son no-lanzamiento (ver más abajo), independientemente de su forma,
  • ambos tienen la forma noexcept(constante-expresión) y los constantes-expresiones son equivalentes,
  • uno excepción de especificación es una noexcept-especificación permitiendo todas las excepciones y el otro es de la forma throw(tipo-id-lista), o
  • ambos son dinámico-excepción especificaciones que tienen el mismo conjunto de tipos ajustados.

.

Si una función virtual tiene un excepción de especificación, todas las declaraciones, incluyendo la definición, de cualquier función que anula esa función virtual en cualquier clase derivada únicamente permitirán excepciones que se permiten por la excepción de especificación de la función virtual de la clase base.

.

Una función con no excepción de especificación o con un excepción de especificación de la forma noexcept(constante-expresión) donde el constante-expresión produce falsa permite todas las excepciones. Un excepción de especificación es no tirar si es de la forma throw(), noexcept, o noexcept(constante-expresión) donde el constante-expresión produce true. Una función con una excepción que no arroja la especificación no permite ninguna excepción.

Intente una compilación más nueva de g ++, donde estos cambios pueden implementarse más completamente.

+0

Acabo de confirmar que funcionó bien con clang ToT y g ++ 4.5.2 (versión mingw). –