Почему std:: exception содержит дополнительные конструкторы в VС++?

То, что я заметил сейчас. Определение exception в стандарт (18.6.1):

class exception {
public :
    exception() throw();
    exception(const exception &) throw();
    exception& operator=(const exception&) throw();
    virtual ~exception() throw();
    virtual const char* what() const throw();
};

Определение exception в MSDN:

class exception {
public:
   exception(); 
   exception(const char *const&);
   exception(const char *const&, int);
   exception(const exception&); 
   exception& operator=(const exception&); 
   virtual ~exception();
   virtual const char *what() const;
};

Похоже, что версия Microsoft позволяет указать сообщение об ошибке для объекта exception, тогда как стандартная версия позволяет вам делать это только для производных классов (но не мешает вам создавать общий exception с сообщением undefined).

Я знаю, что это довольно незначительно, но все же. Есть ли веская причина для этого?

Ответ 1

На самом деле нет веской причины. Реализация MS решила поместить обработку строки в std:: exception, а не в каждый полученный из нее класс (<stdexcept> ).

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

Другие реализации не делают этого таким образом, поэтому переносные программы не должны использовать дополнительные конструкторы.

Ответ 2

Избавление от спецификации броска было хорошей идеей. Хотя они не должны бросать, бросить спецификации, как правило, плохо.

Вставка расширений сделает код не переносимым, но, скорее всего, устранит проблемы среза, где люди "поймают" std:: exception по значению и могут скопировать строку локально из того, что она копирует.

Я не вижу преимущества в int или неявных конструкторах, которые принимают один параметр.