Встроенный метод throw () в C ++ - PullRequest
6 голосов
/ 29 марта 2011

Я пытаюсь определить действительно простой класс исключений.Поскольку это так просто, я хочу сохранить его только в файле .h, но компилятору не нравится throw().Код:

#include <exception>
#include <string>

class PricingException : public virtual std::exception
{
private:
    std::string msg;
public:
        PricingException(std::string message) : msg(message) {}
        const char* what() const throw() { return msg.c_str(); }
        ~PricingException() throw() {}
};

GCC выдает следующие ошибки:

/home/ga/dev/CppGroup/MonteCarlo/PricingException.h:13: error: expected unqualified-id before ‘{’ token
/home/ga/dev/CppGroup/MonteCarlo/PricingException.h:14: error: expected unqualified-id before ‘{’ token

для строк с throw().Любая идея, как это исправить?

РЕДАКТИРОВАТЬ

Я пытался удалить тела проблемных методов, т.е.

virtual ~PricingException() throw();// {}

И теперь яполучить еще более странное сообщение об ошибке:

/home/ga/dev/CppGroup/MonteCarlo/PricingException.h:14: error: looser throw specifier for ‘virtual PricingException::~PricingException()’
/usr/include/c++/4.5/exception:65: error:   overriding ‘virtual std::exception::~exception() throw ()’

Он просто проигнорировал мой спецификатор броска!

Ответы [ 5 ]

4 голосов
/ 29 марта 2011

Попробуйте вместо этого синтаксис C ++ 0x, g ++ 4.5 может быть достаточно свежим, чтобы его поддерживать:

const char* what() const noexcept { return msg.c_str(); }

Однако это не должно иметь значения (формулировка из черновика 3242, раздел [except.spec]:

Две спецификации исключений совместимы , если:

  • оба не выбрасывают (см. Ниже), независимо от ихform,
  • оба имеют форму noexcept( константное выражение ) и константные выражения эквивалентны,
  • one спецификация исключений - это спецификация noexcept , разрешающая все исключения, а другая имеет вид throw( список идентификаторов типов ) или
  • оба являются динамическими исключениями-спецификациями , которые имеют одинаковый набор настроенных типов.

.

Если виртуальныйфункция имеет спецификацию исключений , все объявления, включая определение, любой функции, которая переопределяет эту виртуальную функцию в любом производном классеразрешать только те исключения, которые разрешены спецификацией исключений виртуальной функции базового класса.

.

Функция без спецификация исключений или спецификация исключений в форме noexcept( выражение-константа ), где выражение-константа дает ложьпозволяет все исключения. спецификация исключений является не-броском , если она имеет форму throw(), noexcept или noexcept( константа-выражение )где константное выражение дает true.Функция с ненулевой спецификацией исключений не допускает никаких исключений.

Так что попробуйте новую сборку g ++, где эти изменения могут быть реализованы более полно.

3 голосов
/ 29 марта 2011

Ближайшее, что я нашел в C ++ 0x:

15.4 Спецификации исключений [исключением.spec]

2 Спецификация исключенийдолжен появляться только в объявителе функции для типа функции, указателя на тип функции, ссылки на тип функции или указателя на тип функции-члена, который является типом верхнего уровня объявления или определения, или для такого типа, который отображается как параметрили вернуть тип в объявителе функции.

Мне кажется, что это может запретить использование спецификаций исключений в определениях.

1 голос
/ 29 марта 2011

Мне не удалось воспроизвести это в нескольких версиях g ++.Наиболее вероятная проблема заключается в том, что ранее включенный заголовочный файл имеет проблему, которая в конечном итоге вызывает проблемы с компилятором, когда он видит throw, но не раньше.

0 голосов
/ 31 марта 2011

Наконец-то нашел! @Mike Seymour был прав в своем комментарии - оказывается, что в файле nr3.h (часть кода Numeric Recepies ) определен макрос throw(message).

Что я не понимаю, так это то, почему это влияет на компиляцию файлов, которые не содержат этот файл .h ...

В любом случае, я думаю, что Visual Studio имел другой порядок компиляции или что-то в этом роде, поэтому было просто удачно, что он скомпилирован там, а не в gcc.

0 голосов
/ 29 марта 2011

Вы пробовали throw без ()?в этом примере (я знаю, что в файле .cpp), но вы видите, что броски все не имеют круглых скобок

http://www.glenmccl.com/eh_cmp.htm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...