【问题标题】:Handling "Thrown exception type is not nothrow copy constructible" Warning处理“抛出的异常类型不可复制构造”警告
【发布时间】:2018-03-23 16:44:59
【问题描述】:

在中断 12 年后重返 C++ 开发。我正在使用 JetBrains 的 CLion 软件,它非常棒,因为它为我的课堂设计中可能出现的问题提供了大量输入。我在班级的构造函数 throw 语句中收到的警告之一是:Thrown exception type is not nothrow copy constructible。以下是生成此警告的代码示例:

#include <exception>
#include <iostream>

using std::invalid_argument;
using std::string;

class MyClass {
    public:
        explicit MyClass(string value) throw (invalid_argument);
    private:
        string value;
};

MyClass::MyClass(string value) throw (invalid_argument) {
    if (value.length() == 0) {
        throw invalid_argument("YOLO!"); // Warning is here.
    }

    this->value = value;
} 

这段代码可以编译,我可以对其进行单元测试。但我非常想摆脱这个警告(为了理解我做错了什么,即使它编译)。

【问题讨论】:

  • 为什么要使用 throw 规范?它们已被弃用。 stackoverflow.com/questions/13841559/…
  • throw 说明符带来的痛苦。很痛苦。没有你会更好。
  • 不管 nothrow 副本和异常之间的交互(我不是专家),请注意,您尝试检测的错误不应该用异常处理。这基本上是一个用法或逻辑错误,如果您不希望空字符串作为构造函数输入,则应该终止程序(或检测空字符串是编译时间)。

标签: c++ c++11 exception std clang-tidy


【解决方案1】:

尼尔提供的评论是有效的。在 C++ 11 中,在函数签名中使用 throw 已被弃用,取而代之的是 noexcept。在这种情况下,我的构造函数的签名应该是:

explicit MyClass(string value) noexcept(false);

但是,由于noexcept(false)默认应用于所有函数,除非指定noexceptnoexcept(true),我可以简单地使用:

explicit MyClass(string value);

回到如何修复“抛出的异常类型不是可构造的复制”警告,我发现 this post 很好地解释了问题所在以及如何解决它。

【讨论】:

    猜你喜欢
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 2019-07-11
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多