看一些旧的代码,我们有很多像下面这样的东西:
// This is dumb string do_something(int in) { stringstream out; try { out << std::fixed << in; } catch(std::exception &e) { out << e.what(); } return out.str(); } // Can't we just do this? Can this ever fail? string do_something_better(int in) { stringstream out; out << std::fixed << in; return out.str(); }当一个stringstream读取一个原语时,它能抛出异常吗? 阅读字符串时怎么办?
Looking at some old code we have lots of things like the following:
// This is dumb string do_something(int in) { stringstream out; try { out << std::fixed << in; } catch(std::exception &e) { out << e.what(); } return out.str(); } // Can't we just do this? Can this ever fail? string do_something_better(int in) { stringstream out; out << std::fixed << in; return out.str(); }When a stringstream reads a primitive can it ever throw an exception? What about when reading a string?
最满意答案
总结几个答案
默认情况下,流不会抛出异常。 他们可以,如果他们被启用。
stringstream out; out.exceptions(std::ios::failbit); // throw exception if failbit gets set根据“ Apache C ++标准库用户指南”
标志std :: ios_base :: badbit表示底层流缓冲区的问题。 这些问题可能是:
内存不足 。 没有可用于创建缓冲区的内存,或者由于其他原因(例如从流外部提供)而使缓冲区大小为0,或者流无法为其内部数据分配内存,就像使用std :: ios_base :: iword()和std :: ios_base :: pword()。
基础流缓冲区引发异常。 流缓冲区可能会失去其完整性,如内存不足,代码转换失败或外部设备发生不可恢复的读取错误。 流缓冲区可以通过抛出异常来指示完整性的丢失,该异常由流捕获并导致将badbit设置为流的状态。
通常,您应该记住badbit表示可能无法恢复的错误情况,而failbit表示可能允许您重试失败操作的情况。
所以这似乎是最安全的方式来做到这一点
string do_something(int in) { stringstream out; // This could throw a bad_alloc out << std::fixed << in; // This could set bad or fail bits if(out.good()) { return out.str(); } else { return ""; } }这是过度的,因为根据处理bad_alloc如果创建流失败,有更大的问题需要担心,该程序可能会退出。 因此,假设它通过创建流,这是可能的,但不太可能的badbit被设置。 (流获取分配内存<sizeof(int))。
也不太可能会设置失败位(不确定用于读取堆栈而不是损坏堆栈的用例)。 所以下面的代码就足够了,因为在这一点上从流错误中恢复是不正确的。
string do_something(int in) { stringstream out; out << std::fixed << in; return out.str(); }Summarizing a few answers
By default, streams don't throw exceptions. They can if they are enabled.
stringstream out; out.exceptions(std::ios::failbit); // throw exception if failbit gets setAccording to the Apache C++ Standard Library User's Guide
The flag std::ios_base::badbit indicates problems with the underlying stream buffer. These problems could be:
Memory shortage. There is no memory available to create the buffer, or the buffer has size 0 for other reasons (such as being provided from outside the stream), or the stream cannot allocate memory for its own internal data, as with std::ios_base::iword() and std::ios_base::pword().
The underlying stream buffer throws an exception. The stream buffer might lose its integrity, as in memory shortage, or code conversion failure, or an unrecoverable read error from the external device. The stream buffer can indicate this loss of integrity by throwing an exception, which is caught by the stream and results in setting the badbit in the stream's state.
Generally, you should keep in mind that badbit indicates an error situation that is likely to be unrecoverable, whereas failbit indicates a situation that might allow you to retry the failed operation.
So it seems like the safest way to do this would be
string do_something(int in) { stringstream out; // This could throw a bad_alloc out << std::fixed << in; // This could set bad or fail bits if(out.good()) { return out.str(); } else { return ""; } }This is overkill though because according to Handling bad_alloc if creating the stream fails, there are bigger problems to worry about, and the program is probably going to exit. So assuming it gets past creating the stream, it's possible but extremely unlikely that the badbit gets set. (Stream gets allocated with memory < sizeof(int)).
It's also unlikely that the failbit gets set (not sure of a use case for reading off the stack other than a corrupt stack). So the following code is sufficient, as recovering from a stream error at this point is unlikley.
string do_something(int in) { stringstream out; out << std::fixed << in; return out.str(); }阅读原语时,stringstream是否会引发异常?(Can a stringstream throw an exception when reading a primitive?)看一些旧的代码,我们有很多像下面这样的东西:
// This is dumb string do_something(int in) { stringstream out; try { out << std::fixed << in; } catch(std::exception &e) { out << e.what(); } return out.str(); } // Can't we just do this? Can this ever fail? string do_something_better(int in) { stringstream out; out << std::fixed << in; return out.str(); }当一个stringstream读取一个原语时,它能抛出异常吗? 阅读字符串时怎么办?
Looking at some old code we have lots of things like the following:
// This is dumb string do_something(int in) { stringstream out; try { out << std::fixed << in; } catch(std::exception &e) { out << e.what(); } return out.str(); } // Can't we just do this? Can this ever fail? string do_something_better(int in) { stringstream out; out << std::fixed << in; return out.str(); }When a stringstream reads a primitive can it ever throw an exception? What about when reading a string?
最满意答案
总结几个答案
默认情况下,流不会抛出异常。 他们可以,如果他们被启用。
stringstream out; out.exceptions(std::ios::failbit); // throw exception if failbit gets set根据“ Apache C ++标准库用户指南”
标志std :: ios_base :: badbit表示底层流缓冲区的问题。 这些问题可能是:
内存不足 。 没有可用于创建缓冲区的内存,或者由于其他原因(例如从流外部提供)而使缓冲区大小为0,或者流无法为其内部数据分配内存,就像使用std :: ios_base :: iword()和std :: ios_base :: pword()。
基础流缓冲区引发异常。 流缓冲区可能会失去其完整性,如内存不足,代码转换失败或外部设备发生不可恢复的读取错误。 流缓冲区可以通过抛出异常来指示完整性的丢失,该异常由流捕获并导致将badbit设置为流的状态。
通常,您应该记住badbit表示可能无法恢复的错误情况,而failbit表示可能允许您重试失败操作的情况。
所以这似乎是最安全的方式来做到这一点
string do_something(int in) { stringstream out; // This could throw a bad_alloc out << std::fixed << in; // This could set bad or fail bits if(out.good()) { return out.str(); } else { return ""; } }这是过度的,因为根据处理bad_alloc如果创建流失败,有更大的问题需要担心,该程序可能会退出。 因此,假设它通过创建流,这是可能的,但不太可能的badbit被设置。 (流获取分配内存<sizeof(int))。
也不太可能会设置失败位(不确定用于读取堆栈而不是损坏堆栈的用例)。 所以下面的代码就足够了,因为在这一点上从流错误中恢复是不正确的。
string do_something(int in) { stringstream out; out << std::fixed << in; return out.str(); }Summarizing a few answers
By default, streams don't throw exceptions. They can if they are enabled.
stringstream out; out.exceptions(std::ios::failbit); // throw exception if failbit gets setAccording to the Apache C++ Standard Library User's Guide
The flag std::ios_base::badbit indicates problems with the underlying stream buffer. These problems could be:
Memory shortage. There is no memory available to create the buffer, or the buffer has size 0 for other reasons (such as being provided from outside the stream), or the stream cannot allocate memory for its own internal data, as with std::ios_base::iword() and std::ios_base::pword().
The underlying stream buffer throws an exception. The stream buffer might lose its integrity, as in memory shortage, or code conversion failure, or an unrecoverable read error from the external device. The stream buffer can indicate this loss of integrity by throwing an exception, which is caught by the stream and results in setting the badbit in the stream's state.
Generally, you should keep in mind that badbit indicates an error situation that is likely to be unrecoverable, whereas failbit indicates a situation that might allow you to retry the failed operation.
So it seems like the safest way to do this would be
string do_something(int in) { stringstream out; // This could throw a bad_alloc out << std::fixed << in; // This could set bad or fail bits if(out.good()) { return out.str(); } else { return ""; } }This is overkill though because according to Handling bad_alloc if creating the stream fails, there are bigger problems to worry about, and the program is probably going to exit. So assuming it gets past creating the stream, it's possible but extremely unlikely that the badbit gets set. (Stream gets allocated with memory < sizeof(int)).
It's also unlikely that the failbit gets set (not sure of a use case for reading off the stack other than a corrupt stack). So the following code is sufficient, as recovering from a stream error at this point is unlikley.
string do_something(int in) { stringstream out; out << std::fixed << in; return out.str(); }
发布评论