C++ 如何在 Visual Studio 中处理 noexcept

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18387640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:56:37  来源:igfitidea点击:

How to deal with noexcept in Visual Studio

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

提问by svick

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

我正在尝试创建一个自定义异常,该异常派生自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();
    }
};

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

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

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

错误:'virtual const char* UserException::what() const'的更宽松的抛出说明符

So I add noexcept:

所以我补充说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):

这在 GCC 中运行良好,但在 Visual Studio 中无法编译(因为 VS 2012 不支持noexcept):

error C3646: 'noexcept' : unknown override specifier

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

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.

处理这个问题的推荐方法是什么?我希望使用两个编译器编译相同的代码,并且我使用的是 C++11 功能,因此我无法使用不同的-std.

采纳答案by Praetorian

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 noexcepton later versions of VS by checking the value of _MSC_VER; for VS2012 the value is 1600.

您还可以noexcept通过检查_MSC_VER;的值来修改它以允许更高版本的 VS。对于 VS2012,该值为 1600。

回答by ivan.ukr

"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):

“noexcept”仅自 Visual Studio 2015 起受支持(如此处所述: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

回答by marton78

This check works to see if noexceptis supported:

此检查用于查看是否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

The above works with Clang, GCC and MSVC.

以上适用于 Clang、GCC 和 MSVC。

回答by evan

use BOOST_NOEXCEPTin <boost/config.hpp>

使用BOOST_NOEXCEPT<boost/config.hpp>

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

boost 配置库是为解决此类兼容性问题而设计的。根据文档

If BOOST_NO_CXX11_NOEXCEPTis 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_NOEXCEPTis 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))

如果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))

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.

这里的许多其他答案都有类似的实现,但这个库更干净,经过更好的测试,并且在升级编译器时会做正确的事情。我建议总体上查看 boost 配置库以了解其他功能,尤其是在这个语言不断变化和编译器之间的支持水平不同的时代。

回答by patlecat

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

noexcept是一个最简单的“缺乏” MSVC的处理:只要使用宏_NOEXCEPT这MSVC2013下yvals.h定义。

回答by Anant Simran Singh

Add the following lines in your code in Visual Studio:

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

#ifdef _NOEXCEPT
#define noexcept _NOEXCEPT
#endif

回答by ivan.ukr

What I've recently used is following:

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

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

and then just use NOEXCEPTeverywhere.

然后NOEXCEPT到处使用。

回答by svick

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

似乎旧的throw()(在 C++11 中已弃用)在两个编译器中都有效。所以我把代码改成:

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

回答by Alexei Valyaev

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.

另一种解决方法是创建头文件,并在必要时将其包含在应由 gcc、vc 或 clang 编译的源代码中。

no_except_work_around.h

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

PS> 不包括 case noexcept(false) 但适用于 VC2010,2012,2013, gcc 4.9

回答by It'sNotALie.

#IFs may work, even if a bit hacky.

#IFs 可能工作,即使有点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