Nor*_*rci 8 c++ c++11 system-error c++14
我使用从继承的类std::system_error
进行错误处理,我想控制what()
调用时返回的内容.原因:标准(C++ 11和草案C++ 1y CD - N3690,下面的§引用都是后者)没有说明返回的字符串究竟是what()
什么样子,它只是在§19.5中给出了注释.6.2(14):
注意:返回的NTBS可能是内容
what_arg + ": " + code.message()
. - 结束说明
所以它应被视为依赖于实现.(顺便说一句,不应该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?
}
};
Run Code Online (Sandbox Code Playgroud)
好吧,我不喜欢的一个简单的解决方案可能如下:
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(); }
};
Run Code Online (Sandbox Code Playgroud)
既然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
Run Code Online (Sandbox Code Playgroud)
其中,在std::system_error
§19.5.6.2(2)中成为以下内容:
string(what()).find(what_arg) != string::npos
Run Code Online (Sandbox Code Playgroud)
没有任何人有一个线索,为什么标准试图这么难包括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 */ )
{ }
};
Run Code Online (Sandbox Code Playgroud)
有没有优雅和便携的解决方案?
更新:下面的许多评论都说明错误消息是实现定义的.据我所知,我只想格式化返回的字符串what()
,我不想在所有系统上逐字节等效.想想我想记录它或将它传递给第三方,它应该遵循一些固定的格式(这不是标准建议的).
UPDATE2:我相信std :: system_error不只是OS或STL错误.我可以(并且假设)从中派生自己的类并将它们用于错误报告.如果我正在编写低级API怎么办?顺便说一句,为什么禁止在高级API中使用它?
如果我在API的错误处理部分中将所有参数传递给它的构造函数,则没有涉及实现定义(即未知)的错误字符串,但是我仍然无法在不复制数据的情况下对其进行格式化.
我不知道"优雅和便携"的解决方案,但我认为你在问题中提出的解决方案没有任何问题,即制作你自己的副本what_arg
.
异常对象不会持续很长时间:通常只需要足够长的时间来展开堆栈.此外,字符串输入what_arg
可能不会很长,因为一兆字节what
不太可读.最后,异常对象只会在特殊情况下创建,因此小字符串的"不必要"重复不会对程序的性能产生任何明显影响.
基本上,类设计者选择使类的状态不透明,并且 - 直言不讳 - 你不相信它们从该状态产生可用的结果(可读消息).在这种情况下,您将不得不复制州.这是状态封装的一种并不罕见的结果,一般的解决方案几乎总是复制状态.在这种情况下,成本很小,因此如果控制价值what()
对您来说很重要,您应该接受成本并继续前进.
归档时间: |
|
查看次数: |
635 次 |
最近记录: |