在我们的代码库中,我们不使用c ++异常,这意味着" -fno-exceptions
"在gcc编译选项中(请注意这是我们公司的政策,因此无需争辩)。但是,在这种情况下,如何从抛出异常的标准库中检查构造函数的失败。我已经阅读了一些SO帖子,但仍然没有明确的想法。例如,在c ++ 11中,std::regex("pattern")
可以抛出一个regex_error异常。如果我有以下代码:
class Wrapper {
public:
bool create(std::string pattern) {
try {
m_regex = std::regex(pattern);
m_state = true;
} catch (std::regex_error& e) {
//handle error case
m_state = false;
}
}
private:
std::regex m_regex;
bool m_state;
}
注意:
m_regex = std::regex(pattern);
将致电
explicit basic_regex(const CharT* s, flag_type f = std::regex_constants::ECMAScript)
可以抛出异常并移动赋值运算符
basic_regex& operator=(basic_regex&& __rhs) noexcept
现在,由于没有使用异常的选项,我们如何检查std :: regex构造函数的失败?
class Wrapper {
public:
create(std::string pattern) {
m_regex = std::regex(pattern);
// now, how to check?
// if (m_regex)?
m_state = true;
}
private:
std::regex m_regex;
}
我没有发现std :: regex中有任何状态可能表示失败。
选项1:我可以假设如果正则表达式构造函数失败,将发生abort(),那么以下语句m_state = true
将不会被执行吗?我检查过,似乎abort()通常在启用异常时发生,但没有使用catch。所以这是错误的。
选项2:我可以使用std::regex* ptr_regex = new std::regex("pattern")
,并检查ptr_regex的空值吗?
答案 0 :(得分:2)
这是一个有点未解决的问题,one of the big open problems discussed by SG14是委员会的“低延迟”研究小组。
就标准而言,这是未定义的。例外不是可选的,如果将其关闭,则未指定会发生什么。因此,标准库通常不提供处理错误的替代方法。目前在未来的提案中有一种趋势可以缓解这种情况。例如,当前的Filesystem TS具有非抛出重载,它为所有可能抛出异常的函数返回错误代码。有可能以类似的方式为现有的标准图书馆设施提供非投掷替代方案,但这正是SG14试图弄清楚的。
截至目前,重要的问题是:您的编译器在编译时遇到throw
(或try
/ catch
)时会做什么?异常禁用?如前所述,标准根本没有详细说明,因此这里的任何解决方案都必然是不可移植的。您可能无法通过throw
检测或恢复库指示的错误,因此如果您不能事先排除将抛出异常,您可能希望避免抛出函数(因此,大多数标准库)。
希望将来这种情况会有所改善。
答案 1 :(得分:0)
创建一个库,其目的是包含需要异常的std
实用程序。
在启用例外的情况下编译此库 。
它存储等效的optional<std::regex>
(例如)。它提供了可能失败的构造函数(在库的.cpp
内)调用构造函数,然后尝试/ catch并将失败转换为空regex
。
如果还有其他可以抛出的操作,它会在具有错误返回路径的方法中以类似方式包装它们。也许他们会返回std::experimental::expected<T, error_information>
。
您必须小心ODR以及此库与使用禁用异常的std
库编译的代码之间的链接,因为它们之间的内联函数会有所不同。我现在不详细说明如何避免这个问题。
从一个非常非常快速的谷歌我可以看出,膨胀和一个启用例外的库应该主要限制与该库的大小。测试一下。