据我所知,以便携式方式检查system_error
条件的最佳做法之一是将code()
值与std::errc
枚举中的值进行比较。但是,当我尝试运行以下代码时,这似乎不起作用。
#include <cassert>
#include <cerrno>
#include <system_error>
int main() {
try {
throw std::system_error(ENOENT, std::system_category());
} catch (std::system_error const & e) {
assert(e.code() == std::errc::no_such_file_or_directory); // <- FAILS!?
}
}
我是否误解了这些诊断错误应该如何工作,或者我做错了什么?如何将std::system_error
例外与std::errc
值进行比较?
编辑:代码似乎使用clang++
和libc ++正常工作,但在构建libstdc ++时失败,无论我使用哪个GCC或Clang编译器(和版本)。与PR 60555相关?任何便携式解决方法?
答案 0 :(得分:0)
您没有做错任何事情。正如T.C.的评论所证实在recent similar questions中,这确实是由PR #60555引起的。幸运的是,该错误已在2018年8月8日之前在其VCS中修复:
已修复所有活动分支,因此将在6.5、7.4、8.3和9.1版本中进行修复。
似乎没有很好的解决方法,因此,这只是GCC开发人员发布新版本的GCC的问题,而且要花几年的时间才能将它们合并到流行的发行版中,直到我们最终可以开始使用此出色的现代功能为止C ++ 11。但这就是生活...
答案 1 :(得分:-1)
e.code()
会返回::std::error_code
的实例,该实例已超载operator ==
,导致隐式构造error_condition
对象作为std::errc::no_such_file_or_directory
中的右手表达式。比较将失败,因为异常返回的error_code具有system_category
,而另一个将具有generic_category
。您应该与error_code::value()
进行比较。请注意,此比较需要static_cast
std::errc
值,因为它是enum class
并且不会隐式转换为int。 Working example:
#include <cassert>
#include <cerrno>
#include <system_error>
#include <iostream>
int main()
{
::std::cout << static_cast< int >(ENOENT) << ::std::endl;
::std::cout << static_cast< int >(::std::errc::no_such_file_or_directory) << ::std::endl;
try
{
throw std::system_error(ENOENT, std::system_category());
}
catch(::std::system_error const & e)
{
assert(e.code().value() == static_cast< int >(::std::errc::no_such_file_or_directory));
}
}