如何在禁用异常的情况下检查构造函数的失败 在我们的代码库中,我们不使用GCC编译选项中的C++异常,意思是“ -fNO异常< /代码>(请注意这是我们公司的策略,所以不必争论)。但是,在这种情况下,如何检查抛出异常的标准库中的构造函数的故障。我读过一些SO帖子,但仍然不清楚。例如,在c++11中,std::regex(“模式”) 可以引发正则表达式错误异常。如果我有以下代码: 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; }

如何在禁用异常的情况下检查构造函数的失败 在我们的代码库中,我们不使用GCC编译选项中的C++异常,意思是“ -fNO异常< /代码>(请注意这是我们公司的策略,所以不必争论)。但是,在这种情况下,如何检查抛出异常的标准库中的构造函数的故障。我读过一些SO帖子,但仍然不清楚。例如,在c++11中,std::regex(“模式”) 可以引发正则表达式错误异常。如果我有以下代码: 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; },c++,c++11,exception,constructor,C++,C++11,Exception,Constructor,注: m_regex=std::regex(模式) 将呼叫 explicit basic_regex(const CharT* s, flag_type f = std::regex_constants::ECMAScript) 它可以引发异常并移动赋值运算符 basic_regex& operator=(basic_regex&& __rhs) noexcept 现在,在没有使用exception选项的情况下,我们如何检查std::regex的构造函数的失败 cla

注:
m_regex=std::regex(模式)

将呼叫

explicit basic_regex(const CharT* s, flag_type f = std::regex_constants::ECMAScript)
它可以引发异常并移动赋值运算符

basic_regex& operator=(basic_regex&& __rhs) noexcept
现在,在没有使用exception选项的情况下,我们如何检查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(“模式”)
,并检查ptr_regex的空值?

这是一个尚未解决的问题,也是委员会的“低延迟”研究组

就标准而言,这只是未定义的。异常不是可选的,如果您关闭它们,会发生什么是未指定的。因此,标准库通常不提供处理错误的替代方法。目前有一种趋势,就是在今后的提案中有所缓解。例如,当前文件系统TS具有非抛出重载,这些重载为所有可能抛出异常的函数返回错误代码。以类似的方式为现有的标准图书馆设施提供非投掷的替代品是可能的,但这正是SG14试图解决的问题

到目前为止,重要的问题是:如果编译器在禁用异常的情况下编译时遇到
抛出
(或
尝试
/
捕获
),它会做什么?如前所述,标准根本没有规定这一点,因此这里的任何解决方案都必须是不可移植的。很可能您无法通过
抛出
来检测库指示的错误或从中恢复,因此如果您无法事先排除将抛出异常,您可能希望避开抛出函数(因此,大多数标准库都是如此)


希望将来这种情况会有所改善。

创建一个库,其目的是包装需要
std
实用程序的异常

此库在编译时启用了异常

它或者存储一个等价的
可选的
(例如)。它提供了可能失败的构造函数(在库的
.cpp
中)调用构造函数,然后尝试/捕获并将失败转换为空的
regex

如果有其他操作可以抛出,它会将它们同时包装在具有错误返回路径的方法中。可能它们返回
std::experimental::expected

您必须小心使用ODR以及此库和使用异常禁用的
std
库编译的代码之间的链接,因为它们之间的内联函数会有所不同。我不知道如何避免这个问题的细节。在某些平台上,std库函数可能是动态链接的,您可能会加载以错误方式编译的错误函数。再说一遍,我不知道如何解决这个问题


从一个非常快速的google上我可以看出,膨胀和启用异常的一个库应该主要限制为与该库的大小成比例。对此进行测试。

您不能。如果你不允许使用异常(甚至只是为了捕捉),你必须避免使用STL。正如@ Gonmator所说,除了它不仅仅是STL:你必须避免C++标准库的大部分内容,特别是正则表达式。除非是出于非常好的原因,比如资源非常少的嵌入式编程,或者为了处理遗留代码库(谷歌就是这么做的),否则,如果可能的话,我们可以在其他地方找到工作。因为,有一项重要政策是由不称职的人制定的,其他政策也可能同样不好。例如,当首席执行官透露缺乏职业道德指南针时,情况也是如此:这可能影响了整个组织。@Cheersandhth.-Alf,是的,不幸的是,这属于你提到的一个(实际上是两个)好理由。我真的在互联网上搜索了一些作品,但到目前为止还是一无所获。是的,我们真的被困在这上面了。但我们必须找到一些解决方案或解决办法,因为我们或我们的客户等不及委员会了。@pepero我感觉到了你的痛苦。您可能希望留意其他实现。出于这一原因和其他原因,许多供应商提出了自己的标准图书馆设施实施方案。”“嵌入式STL”是一个很好的互联网搜索关键词。有时Boost提供了附加保证的实现。不幸的是,我不知道有任何
std::regex
的实现可以解决您的问题。