спецификация исключения переопределяющей функции более слабая, чем базовая версия - PullRequest
0 голосов
/ 18 декабря 2018

Я хочу настроить класс исключения, вот код:

class TestException : std::exception{
  public:
  const char *what() const override {
    return "TestException";
  }
};

Я использовал Clion, и среда IDE выдает предупреждение о функции what(): exception specification of overriding function is more lax than base version

Но если я соберу код с помощью gcc, предупреждений не будет.Я использовал c ++ 14, gcc 6.5.0

Кто-нибудь может помочь объяснить, что означает предупреждение, и могу ли я просто проигнорировать его?

Ответы [ 3 ]

0 голосов
/ 18 декабря 2018

Предупреждение, с которым вы сталкиваетесь, связано с тем, что вы используете C ++ 14, если вы скомпилируете с C ++ 17, это станет ошибкой.Следовательно, я бы не рекомендовал игнорировать его.

Что происходит?

std::exception определяет метод what как: virtual const char* what() const noexcept;.Вы наследуете от этого метода и повторно реализуете его без указания noexcept.В результате вы говорите, что ваша реализация может генерировать исключения, в то время как базовый метод указывает, что это никогда не должно генерироваться.(И вызывающие абоненты примут это так)

Это было исправлено в C ++ 17, что сделало noexcept частью системы типов, и требует от вас исправить этот код:

const char *what() const noexcept override
0 голосов
/ 18 декабря 2018

what из std::exception - это функция virtual, а функция virtual в производном классе не может иметь более слабую спецификацию исключений , чем функция, в которой она переопределяетбазовый класс.

Это упомянуто в разделе «Спецификации исключений» в стандарте.

18.4 Спецификации исключений [кроме.spec]
...
4. Если виртуальная функция имеет спецификацию не-генерирующего исключения, все объявления, включая определение любой функции, которая переопределяет эту виртуальную функцию в любом производном классе, должны иметь спецификацию не-генерирующего исключения, если только эта функция не являетсяопределяется как удаленный.

И данный пример (который несколько похож на код в вопросе) также иллюстрирует это.

struct B 
{ 
  virtual void f() noexcept; 
  virtual void g(); 
  virtual void h() noexcept = delete; 
};
struct D: B 
{ 
  void f(); // ill-formed 
  void g() noexcept; // OK 
  void h() = delete; // OK 
}; 

Объявление D::f плохо-произведенный, потому что у него есть спецификация потенциально выбрасывающего исключения, в то время как B::f имеет спецификацию не выбрасывающего исключения.

Решение состоит в том, чтобы изменить ваш код следующим образом:

class TestException : std::exception{
  public:
  const char *what() const noexcept override {
    return "TestException";
  }
};

См. сборник здесь.

0 голосов
/ 18 декабря 2018

what функция-член std::exception объявлена ​​как noexcept начиная с C ++ 11.Поэтому вам также следует сделать переопределенную what noexcept.(На самом деле, именно об этом говорится в сообщении об ошибке.)

Обратите внимание, что ключевое слово noexcept должно стоять перед ключевым словом override (см., Например, Порядок переопределения и noexcept в стандарте. для деталей).

...