gpt4 book ai didi

c++ - 在不复制数据的情况下,决定 what() 从继承自 std::system_error 的类返回什么的符合标准的方法是什么?

转载 作者:可可西里 更新时间:2023-11-01 17:45:46 26 4
gpt4 key购买 nike

我使用从 std::system_error 继承的类进行错误处理,我想控制调用 what() 时返回的内容。原因:标准(C++11 和 C++1y CD 草案 - N3690,下面的 § 引用是后者)没有指定 what() 返回的字符串应该是什么样子就像,它只是在 §19.5.6.2 (14) 中给出注释:

Note: The returned NTBS might be the contents of what_arg + ": " +
code.message()
. — end note

因此它应被视为依赖于实现。 (顺便说一句,不应该是 code().message() 而不是 code.message() 吗?)

所以,问题是:如果我想符合标准并且不依赖于实现(即想要可移植),我该如何精确定义 what() 返回的字符串?

对于那些喜欢代码的人:

class my_class : public std::system_error {
public:
my_class(std::error_code ec, std::string const & what_arg)
: system_error(ec, /* this string is not required to be equal to what is returned by what() */)
{
// ok, try it here
// but what is the name of the member storing the string?
}
const char * what() const noexcept
{
// ok, try it here
// but how to access what_arg in its unaltered form?
}
};

好的,我不喜欢的一个简单的解决方案如下:

class my_class : public std::system_error {
std::string my_what;
public:
my_class(std::error_code ec, std::string const & what_arg)
: system_error(ec, what_arg),
my_what( /* construct my what string */ )
{ }
const char * what() const noexcept
{ return my_what.c_str(); }
};

因为 std::exception::what() 是虚拟的,所以它可以工作,但是有没有更优雅的方式而不使用任何实现细节?我不喜欢存储两个字符串的想法:一个在 std::system_error 中,另一个在 my_what 中。

问题的根源:std::runtime_error——恰好是 std::system_error 的父类——在 §1.9.2.6 (3) 中有一个确切的要求,构造函数的后置条件:

strcmp(what(), what_arg.c_str()) == 0

其中,在 std::system_error 的情况下,在 §19.5.6.2 (2) 中变为以下内容:

string(what()).find(what_arg) != string::npos

有人知道为什么标准如此努力地将 code().message() 包含到 what() 中吗?请注意,code() 返回错误代码对象,因此任何人都可以随时在字符串中包含 code().message()(即使在出现异常时)这个类的被捕获了)。

如果 std::system_error 的要求与 std::runtime_error 的要求相同,我可以这样写:

class my_class : public std::system_error {
public:
my_class(std::error_code ec, std::string const & what_arg)
: system_error(ec, /* build my what string here */ )
{ }
};

有没有优雅便携的解决方案?

更新:下面的许多评论都指出错误消息是实现定义的。我明白,我只是想格式化 what() 返回的字符串,我不想让它在所有系统上逐字节等效。想想我想记录它或将它传递给第 3 方,它应该遵循某种固定格式(这不是标准建议的格式)。

更新 2:我相信 std::system_error 不仅仅针对操作系统或 STL 错误。我可以(并且假设)从中派生出我自己的类并将它们用于错误报告。如果我正在编写低级 API 怎么办?顺便问一下,为什么禁止在高级 API 中使用它?

如果我在我的 API 的错误处理部分将所有参数传递给它的构造函数,则没有没有实现定义(即未知)涉及错误字符串,但我仍然无法在不复制的情况下格式化它数据。

最佳答案

我不知道“优雅且便携”的解决方案,但我认为您在问题中提出的解决方案没有任何问题,即制作您自己的 what_arg.

异常对象不会持续很长时间:通常,只够展开堆栈。此外,what_arg 中的字符串不太可能很长,因为 1 兆字节的 what 可读性不佳。最后,异常对象只会在特殊情况下创建,因此“不必要”的小字符串重复不会对程序性能产生任何明显影响。

基本上,类设计者已选择使类的状态不透明,并且 - 坦率地说 - 您不相信他们会从该状态产生可用的结果(可读消息)。在这种情况下,您将不得不复制状态。这是状态封装的常见结果,一般的解决方案几乎总是复制状态。在这种情况下,成本很小,因此如果控制 what() 的值对您很重要,您应该接受成本并继续前进。

关于c++ - 在不复制数据的情况下,决定 what() 从继承自 std::system_error 的类返回什么的符合标准的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17458421/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com