c++ visual-studio-2012 c++11 noexcept

c++ - Cómo lidiar con noexcept en Visual Studio



visual-studio-2012 c++11 (10)

"noexcept" solo es compatible desde Visual Studio 2015 (como se indica aquí: https://msdn.microsoft.com/en-us/library/wfa0edys.aspx ). He utilizado el siguiente código con Visual Studio 2013 (derivado de los ejemplos anteriores):

#if !defined(HAS_NOEXCEPT) #if defined(__clang__) #if __has_feature(cxx_noexcept) #define HAS_NOEXCEPT #endif #else #if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || / defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026 #define HAS_NOEXCEPT #endif #endif #ifdef HAS_NOEXCEPT #define NOEXCEPT noexcept #else #define NOEXCEPT #endif

Estoy intentando crear una excepción personalizada que se deriva de std::exception y anula what() . Al principio, lo escribí así:

class UserException : public std::exception { private: const std::string message; public: UserException(const std::string &message) : message(message) {} virtual const char* what() const override { return message.c_str(); } };

Esto funciona bien en VS2012, pero no se compila en GCC 4.8 con -std=c++11 :

error: especificador de tiro más flexible para ''virtual const char * UserException :: what () const''

Entonces agrego noexcept :

virtual const char* what() const noexcept override

Esto funciona bien en GCC, pero no se compila en Visual Studio (porque VS 2012 no admite noexcept ):

error C3646: ''noexcept'': especificador de anulación desconocido

¿Cuál es la forma recomendada de lidiar con esto? Quiero el mismo código para compilar con ambos compiladores y estoy usando las características de C ++ 11, por lo que no puedo compilar con diferentes -std .


Agregue las siguientes líneas en su código en Visual Studio:

#ifdef _NOEXCEPT #define noexcept _NOEXCEPT #endif


El noexcept es una de las "carencias" más fáciles de MSVC: simplemente use la macro _NOEXCEPT que en MSVC2013 se define en yvals.h.


Esta comprobación funciona para ver si noexcept es compatible:

// Is noexcept supported? #if defined(__clang__) && __has_feature(cxx_noexcept) || / defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || / defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 180021114 # define NOEXCEPT noexcept #else # define NOEXCEPT #endif

Lo anterior funciona con Clang, GCC y MSVC.


La otra forma de hacerlo es crear un archivo de encabezado e incluirlo si es necesario en su código fuente que debería compilarse mediante gcc, vc o clang.

no_except_work_around.h

#ifndef no_except_work_around_H #define no_except_work_around_H #if (_MSC_VER <= 1800) #include <xkeycheck.h> #define noexcept #endif #endif //no_except_work_around_H

=============================================== ===

PS> no cubre caso no salvo (falso) pero funciona bien para VC2010,2012,2013, gcc 4.9


Lo que he usado recientemente es lo siguiente:

#ifdef _MSC_VER #define NOEXCEPT _NOEXCEPT #else #define NOEXCEPT noexcept #endif

y luego solo use NOEXCEPT todas partes.


Parece que el antiguo throw() (obsoleto en C ++ 11) funciona en ambos compiladores. Así que cambié el código a:

virtual const char* what() const throw() override


Usa una macro

#ifndef _MSC_VER #define NOEXCEPT noexcept #else #define NOEXCEPT #endif

Y luego define la función como

virtual const char* what() const NOEXCEPT override

También puede modificar eso para permitir noexcept en versiones posteriores de VS verificando el valor de _MSC_VER ; para VS2012 el valor es 1600.


use BOOST_NOEXCEPT en <boost/config.hpp>

La biblioteca de configuración de impulso se diseñó para problemas de compatibilidad como este. De acuerdo con el documento :

Si se define BOOST_NO_CXX11_NOEXCEPT (es decir, compiladores que cumplen con C ++ 03) estas macros se definen como:

#define BOOST_NOEXCEPT #define BOOST_NOEXCEPT_OR_NOTHROW throw() #define BOOST_NOEXCEPT_IF(Predicate) #define BOOST_NOEXCEPT_EXPR(Expression) false

Si BOOST_NO_CXX11_NOEXCEPT no está definido (es decir, compiladores que cumplen con C ++ 11) se definen como:

#define BOOST_NOEXCEPT noexcept #define BOOST_NOEXCEPT_OR_NOTHROW noexcept #define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) #define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression))

Muchas de las otras respuestas aquí tienen una implementación similar, pero esta biblioteca es más limpia, mejor probada, y hará lo correcto cuando se actualice su compilador. Recomiendo mirar la biblioteca de configuración de boost en general para otras características, especialmente en este momento de flujo de idioma y niveles variables de soporte entre los compiladores.


#IF s puede funcionar, aunque sea un poco hacky.

Podrías hacer esto:

#if __GNUG__ virtual const char* what() const noexcept override #else virtual const char* what() const override #endif //method body