Ответ 1
Мнение играет здесь роль. Проблема в том, что std::exception
не имеет конструктора, который принимает строковый аргумент; это расширение MSVC. Я вижу два пути:
- Не передавать строковый аргумент
- Не используйте
std::exception
Первый случай прост; просто используйте
throw std::exception();
Недостатком является то, что вы не получите описательное сообщение об ошибке.
Если сообщение об ошибке важно, использование std::exception
напрямую не является опцией. В этом случае вы можете использовать либо std::logic_error
либо std::runtime_error
, которые наследуют std::exception
и имеют конструкторы, принимающие строковый аргумент, поэтому
throw std::runtime_error("Unable to format Device");
может решить проблему. catch
которые поймали std::exception
, также поймают std::runtime_error
. Однако есть одна потенциальная проблема: catch
clauses, которые поймают std::runtime_error
, не поймали бы std::exception
но поймают это.
Это похоже на крошечный случай, и вполне возможно, что это не проблема для вас. Если, однако, существует вероятность, что в стеке вызовов есть предложение catch
, которое ловит std::runtime_error
но не должно улавливать исключение, созданное этим кодом, вы можете получить свой собственный класс исключения из std::exception
, который принимает строковый аргумент. Поскольку класс является новым, он не будет улавливаться существующими предложениями catch
. Например:
class descriptive_exception : public std::exception {
public:
descriptive_exception(std::string const &message) : msg_(message) { }
virtual char const *what() const noexcept { return msg_.c_str(); }
private:
std::string msg_;
}
А потом
throw descriptive_exception("Unable to format Device");
Это, возможно, не очень красиво, и маловероятно, что это необходимо, поэтому более вероятным решением является использование std::runtime_error
или std::logic_error
(или класс, полученный из одного из них).
Является ли std::logic_error
или std::runtime_error
более уместным, не очень понятно; в этом случае я, вероятно, поеду с std::runtime_error
потому что ошибка не кажется даже теоретически предсказуемой, но учитывая, что std::domain_error
и std::future_error
получают из std::logic_error
, это не будет полностью неуместно в этой иерархии. Это, я думаю, вопрос мнения.