如何可移植地将 std::system_error 异常与 std::errc 值进行比较?
How to portably compare std::system_error exceptions to std::errc values?
据我所知,以便携方式检查 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 相关?任何便携式解决方法?
e.code()
returns ::std::error_code
的一个实例,它重载了 operator ==
,这导致 error_condition
对象隐式构造为 std::errc::no_such_file_or_directory
。比较将失败,因为异常返回的 error_code 具有 system_category
而另一个将具有 generic_category
。您应该与 error_code::value()
进行比较。请注意,此比较需要 std::errc
的 static_cast
值,因为它是 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));
}
}
你没有做错任何事。正如 T.C 在评论中所确认的那样。并在 , this is indeed caused by PR #60555。幸运的是,到 2018 年 8 月 8 日,这个错误已经在他们的 VCS 中得到修复:
Fixed on all active branches, so will be fixed in the 6.5, 7.4, 8.3 and 9.1 releases.
这似乎没有好的解决方法,所以现在只是 GCC 开发人员发布新版本的 GCC 的问题,并且在这些版本被纳入流行的发行版之前,我们最终可以开始使用这个不错的版本还需要几年的时间C++11 的现代特性。但这就是生活...
据我所知,以便携方式检查 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 相关?任何便携式解决方法?
e.code()
returns ::std::error_code
的一个实例,它重载了 operator ==
,这导致 error_condition
对象隐式构造为 std::errc::no_such_file_or_directory
。比较将失败,因为异常返回的 error_code 具有 system_category
而另一个将具有 generic_category
。您应该与 error_code::value()
进行比较。请注意,此比较需要 std::errc
的 static_cast
值,因为它是 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));
}
}
你没有做错任何事。正如 T.C 在评论中所确认的那样。并在
Fixed on all active branches, so will be fixed in the 6.5, 7.4, 8.3 and 9.1 releases.
这似乎没有好的解决方法,所以现在只是 GCC 开发人员发布新版本的 GCC 的问题,并且在这些版本被纳入流行的发行版之前,我们最终可以开始使用这个不错的版本还需要几年的时间C++11 的现代特性。但这就是生活...