如何处理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