How to deal with noexcept in Visual Studio

匿名 (未验证) 提交于 2019-12-03 02:45:02

问题:

I'm trying to create a custom exception that derives from std::exception and overrides what(). At first, I wrote it like this:

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

This works fine in VS2012, but it doesn't compile in GCC 4.8 with -std=c++11:

error: looser throw specifier for ‘virtual const char* UserException::what() const’

So I add noexcept:

virtual const char* what() const noexcept override 

This works fine in GCC, but it doesn't compile in Visual Studio (because VS 2012 doesn't support noexcept):

error C3646: 'noexcept' : unknown override specifier

What is the recommended way to deal with this? I want the same code to compile with both compilers and I'm using C++11 features, so I can't compile with different -std.

回答1:

Use a macro

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

And then define the function as

virtual const char* what() const NOEXCEPT override 

You could also modify that to allow noexcept on later versions of VS by checking the value of _MSC_VER; for VS2012 the value is 1600.



回答2:

"noexcept" is only supported since the Visual Studio 2015 (as stated here: https://msdn.microsoft.com/en-us/library/wfa0edys.aspx). I have used following code with Visual Studio 2013 (derived from above examples):

#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 


回答3:

This check works to see if noexcept is supported:

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

The above works with Clang, GCC and MSVC.



回答4:

use BOOST_NOEXCEPT in <boost/config.hpp>

The boost config library was designed for compatibility issues like this. According to the doc:

If BOOST_NO_CXX11_NOEXCEPT is defined (i.e. C++03 compliant compilers) these macros are defined as:

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

If BOOST_NO_CXX11_NOEXCEPT is not defined (i.e. C++11 compliant compilers) they are defined as:

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

Many of the other answers here have a similar implementation but this library is cleaner, better tested, and will do the right thing when your compiler is upgraded. I recommend looking at the boost config library in general for other features, especially in this time of language flux and varying levels of support among compilers.



回答5:

The noexcept is one of the easiest "lacks" of MSVC to deal with: Just use the macro _NOEXCEPT which under MSVC2013 is defined in yvals.h .



回答6:

Add the following lines in your code in Visual Studio:

#ifdef _NOEXCEPT #define noexcept _NOEXCEPT #endif 


回答7:

What I've recently used is following:

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

and then just use NOEXCEPT everywhere.



回答8:

It seems that the old throw() (deprecated in C++11) works in both compilers. So I changed the code to:

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


回答9:

The other way to go around is create header file and include it if necessary in your source code that should be compile by gcc, vc,or 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 

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

P.S> doesn't cover case noexcept(false) but works fine for VC2010,2012,2013, gcc 4.9



回答10:

#IFs may work, even if a bit hacky.

You could just do this:

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


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!