如何处理Visual Studio中的noexcept

我试图创build一个自定义的exception,从std::exception并重写what() 。 起初,我是这样写的:

 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(); } }; 

这在VS2012中工作正常,但它不会在GCC 4.8中用-std=c++11编译:

错误:宽松抛出说明符'虚拟常量字符* UserException ::什么()const'

所以我加了noexcept

 virtual const char* what() const noexcept override 

这在GCC中工作正常,但在Visual Studio中不能编译(因为VS 2012不支持noexcept ):

错误C3646:'noexcept':未知的覆盖说明符

什么是处理这个build议的方式? 我想要使​​用这两个编译器编译相同的代码,我使用C ++ 11function,所以我不能用不同的-std编译。

使用macros

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

然后定义函数为

 virtual const char* what() const NOEXCEPT override 

您也可以通过检查_MSC_VER的值来修改它以允许在VS的更高版本上_MSC_VER ; 对于VS2012的值是1600。

仅在Visual Studio 2015(如此处所述: https ://msdn.microsoft.com/en-us/library/wfa0edys.aspx)中支持“noexcept”。 我在Visual Studio 2013中使用了以下代码(从上面的例子中得到):

 #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 

此检查可以查看是否支持noexcept

 // 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 

以上与Clang,GCC和MSVC一起工作。

<boost/config.hpp>使用BOOST_NOEXCEPT

boostconfiguration库是为这样的兼容性问题而devise的。 根据文件 :

如果BOOST_NO_CXX11_NOEXCEPT被定义(即符合C ++ 03的编译器),这些macros被定义为:

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

如果BOOST_NO_CXX11_NOEXCEPT没有被定义(即符合C ++ 11的编译器),它们被定义为:

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

这里的许多其他答案都有类似的实现,但是这个库更干净,更好的testing,并且在编译器升级时会做正确的事情。 对于其他function,我build议一般查看boostconfiguration库,尤其是在编译器的语言stream量和支持程度不同的时候。

在Visual Studio中的代码中添加以下行:

 #ifdef _NOEXCEPT #define noexcept _NOEXCEPT #endif 

noexcept是MSVC最容易处理的“缺乏”之一:只要使用在MSVC2013中定义的macros_NOEXCEPT在yvals.h中。

看起来旧的throw() (在C ++ 11中被弃用)在两个编译器中都可以使用。 所以我改变了代码:

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

另一种方法是创build头文件,并在必要时将其包含在应由gcc,vc或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>不包括案件noexcept(false),但为VC2010,2012,2013,海湾合作委员会4.9工作正常

我最近使用的是以下内容:

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

然后到处使用NOEXCEPT

#IF可能工作,即使有点hacky。

你可以这样做:

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