带有char *构造函数的异常类

时间:2015-02-21 00:30:08

标签: c++ visual-studio c++11 gcc

我在VS2008上看到了以下代码

if (!CreateProcess( NULL,
                    const_cast<LPWSTR>(ss.str().c_str()),
                    NULL,
                    NULL,
                    FALSE,
                    CREATE_NO_WINDOW|NORMAL_PRIORITY_CLASS,
                    NULL,
                    NULL,
                    &si,
                    &pi))
{
    throw   std::exception("Unable to format Device");
}

现在我将代码移植到mingw gcc,我收到了错误

error: no matching function for call to 'std::exception::exception(const char [23])'

调查问题我注意到Visual Studio有一个文件异常,它有一个异常类并且确实接受了char *。一些定义看起来像这样

   __CLR_OR_THIS_CALL exception();
    __CLR_OR_THIS_CALL exception(const char *const&);
    __CLR_OR_THIS_CALL exception(const char *const&, int);
    __CLR_OR_THIS_CALL exception(const exception&);
    exception& __CLR_OR_THIS_CALL operator=(const exception&);
    virtual __CLR_OR_THIS_CALL ~exception();
    virtual const char * __CLR_OR_THIS_CALL what() const;

我的问题是我应该如何规避mingw gcc上的构建问题?我应该创建一个继承自std :: runtime_error的新类并将其抛出吗?

1 个答案:

答案 0 :(得分:40)

意见在这里发挥作用。问题是std::exception没有带字符串参数的构造函数;这是MSVC扩展。我认为有两种方法可以解决这个问题:

  1. 不传递字符串参数
  2. 请勿使用std::exception
  3. 第一种情况很简单;只需使用

    throw std::exception();
    

    缺点是您没有收到描述性错误消息。

    如果错误消息很重要,则不能直接使用std::exception。在这种情况下,您可以使用继承std::logic_error的{​​{1}}或std::runtime_error,并使构造函数采用字符串参数,所以

    std::exception

    可能已经解决了这个问题。发现throw std::runtime_error("Unable to format Device"); 的{​​{1}}条款也会抓住catch。但是有一个潜在的问题:捕获std::exception的{​​{1}}子句不会捕获std::runtime_error但会抓住这个。

    这看起来像是一个角落的情况,它完全有可能对你来说不是问题。但是,如果有可能在调用堆栈中有一个catch子句捕获std::runtime_error但是不应该捕获此代码抛出的异常,那么您可以从{{{{{}派生自己的异常类。 1}}确实需要一个字符串参数。由于该类是新的,因此现有的std::exception子句不会捕获它。例如:

    catch

    然后

    std::runtime_error

    这可能不是很漂亮,并且它不太可能是必要的,因此更可能的解决方案是使用std::exceptioncatch(或从其中一个派生的类)。< / p>

    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_errorstd::logic_error来自std::runtime_error,它不会在该等级中完全不合适。我认为这是一个意见问题。