我在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的新类并将其抛出吗?
答案 0 :(得分:40)
意见在这里发挥作用。问题是std::exception
没有带字符串参数的构造函数;这是MSVC扩展。我认为有两种方法可以解决这个问题:
std::exception
第一种情况很简单;只需使用
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::exception
或catch
(或从其中一个派生的类)。< / 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_error
和std::logic_error
来自std::runtime_error
,它不会在该等级中完全不合适。我认为这是一个意见问题。