如何在Visual Studio中处理noexcept
How to deal with noexcept in Visual Studio
我正在尝试创建一个从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中运行良好,但在带有-std=c++11
:的GCC 4.8中无法编译
错误:"virtual const char*UserException::what()const"的抛出说明符更宽松
所以我添加了noexcept
:
virtual const char* what() const noexcept override
这在GCC中运行良好,但在Visual Studio中无法编译(因为VS 2012不支持noexcept
):
错误C3646:"noexcept":未知的重写说明符
建议的处理方法是什么?我希望用两个编译器编译相同的代码,并且我使用C++11功能,所以我不能用不同的-std
编译。
使用宏
#ifndef _MSC_VER
#define NOEXCEPT noexcept
#else
#define NOEXCEPT
#endif
然后将函数定义为
virtual const char* what() const NOEXCEPT override
您也可以通过检查_MSC_VER
的值来修改它,以允许在VS的更高版本上使用noexcept
;对于VS2012,该值为1600。
只有在Visual Studio 2015之后才支持"noexcept"(如下所述:https://msdn.microsoft.com/en-us/library/wfa0edys.aspx)。我在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
boost配置库是为解决此类兼容性问题而设计的。根据文件:
如果定义了
BOOST_NO_CXX11_NOEXCEPT
(即符合C++03的编译器),则这些宏被定义为:#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))
这里的许多其他答案都有类似的实现,但这个库更干净,测试更好,并且在编译器升级时会做正确的事情。我建议查看boost配置库的其他功能,尤其是在语言不断变化和编译器之间支持程度不同的情况下。
noexcept是MSVC最容易处理的"缺点"之一:只需使用宏_NOEXCEPT
,该宏在MSVC2013下在yvals.h中定义。
在Visual Studio中的代码中添加以下行:
#ifdef _NOEXCEPT
#define noexcept _NOEXCEPT
#endif
我最近使用的是:
#ifdef _MSC_VER
#define NOEXCEPT _NOEXCEPT
#else
#define NOEXCEPT noexcept
#endif
然后在任何地方都使用CCD_ 15。
似乎旧的throw()
(在C++11中已弃用)适用于这两个编译器。所以我把代码改成:
virtual const char* what() const throw() override
另一种方法是创建头文件,并在必要时将其包含在应该由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
=============================================
p.S>不包括案件noexcept(false)但适用于VC201020122013,gcc 4.9
#IF
可能会工作,即使有点麻烦。
你可以这样做:
#if __GNUG__
virtual const char* what() const noexcept override
#else
virtual const char* what() const override
#endif
//method body
将以下路径添加到其他包含目录
C:Program Files (x86)Microsoft Visual Studio 14.0VCinclude
在这个位置有一个名为"yvals.h"的文件,其中包含_NOEXCEPT 的定义
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用流处理接收到的数据
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 基于多个条件处理地图中的所有元素
- 如何用数字处理log(0)
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- 错误处理.将系统错误代码映射到泛型
- 从文本文件中读取时钟时间和事件时间并进行处理
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 用于矢量处理的多个线程
- 对字符串进行排序时,在c++中处理sort()
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- 处理除以零会导致<csignal>意外行为
- 是否可以在c++中处理字符串流中的各个元素
- 如何在Visual Studio中处理noexcept