c++ 虚函数的异常规范与重写函数的异常规范不兼容

lc8prwob  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(309)

我在使用intel的icpc(版本14.0.1,使用-std=c++11)时得到了这个错误信息,而clang(版本3.4)和gcc(版本4.8.1)都很高兴。一个典型的违规代码是:

#include <vector>
namespace test {
  struct A
  {
    virtual bool foo(std::size_t) const = 0;
    virtual ~A() = default;
  };

  struct B
  : A
  {
    const std::vector<double> V;
    const double X;
    bool foo(std::size_t i) const { return V.at(i) > X; }
    virtual bool bar(std::size_t i) const { return V.at(i) < X; }
    B(double x, std::vector<double> const &v)
      : V(v), X(x) {}
    ~B() = default;
  };
}

因为test::A是抽象的,所以最好有一个虚析构函数。然而,icpc抱怨(编译错误不是警告)
虚函数“test::B::~B”的异常规范与重写函数“test::A::~A”的异常规范不兼容
我认为这一切都是英特尔编译器的错误。对不对?
PS.我注意到一个相关的question,在C11之前问过。当throw被弃用(并被noexcept取代)时,我真的很担心C11。

yx2lnoni

yx2lnoni1#

此错误消息表明类的析构函数与基类的析构函数具有不同的异常规范。编译器隐式地为你的派生类声明了一个析构函数,这是不兼容的。
若要解决此问题,请使用适当的异常规范显式定义类的析构函数,以匹配基类的异常规范。最有可能的是,基类析构函数被声明为noexcept

// ...

class DerivedClass : public BaseClass {
public:
    // Explicitly define a noexcept destructor
    virtual ~DerivedClass() noexcept = default;

    // ... (rest of your class definition)
};

相关问题