sv9*_*v90 8 c++ iostream exception
我最近了解到,人们可以选择加入iostreams的异常.为了不必手动检查文件是否打开我尝试了,并遇到这种行为:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
void test(std::istream& is, bool exceptions) {
try {
if (exceptions)
is.exceptions(std::istream::failbit);
std::vector<int> input;
std::copy(std::istream_iterator<int>{is}, {}, std::back_inserter(input));
for (auto x : input) {
std::cout << x << '\n';
}
}
catch (const std::ios_base::failure& f) {
std::cerr << "Caught error: " << f.what() << '\n';
}
}
int main() {
// Emulates file
std::stringstream ss("1 2 3\n4 5 6\n7 8 9\n");
test(ss, true);
}
Run Code Online (Sandbox Code Playgroud)
当异常被设置时,这可以正常工作.但是,当我使用异常时,我会抛出一个basic_ios::clear,我想不出原因.
basic_ios::clear未列出可failbit根据cppreference设置的函数.
提前致谢.
编辑:下面的答案已经回答了为什么会这样.我现在的另一个问题是如何避免这种例外?我的第二次尝试是std::copy通过这个循环替换:
for (int n; is >> n;) {
input.push_back(n);
}
Run Code Online (Sandbox Code Playgroud)
产生了同样的例外.或者这种行为是否有意?
注意: clang不显示此行为.
Jonesinator 已经给了你异常的原因,我想强调的是,错误的存在与异常无关。事实上,您的功能并不等效,您在无异常分支中的操作之后不检查流。事实上,错误正在悄然发生。如果您以等效的方式编写这两个函数,您将得到等效的结果:
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
void test_exception(std::istream& is) {
try {
is.exceptions(std::istream::failbit);
std::vector<int> input;
std::copy(std::istream_iterator<int>{is}, {}, std::back_inserter(input));
for (auto x : input) {
std::cout << x << '\n';
}
}
catch (const std::ios_base::failure& f) {
std::cout << "Caught error: " << f.what() << '\n';
}
}
void test_error_code(std::istream& is) {
std::vector<int> input;
std::copy(std::istream_iterator<int>{is}, {}, std::back_inserter(input));
if (!is.good()) {
std::cout << "Caught error!" << std::endl;
return;
}
for (auto x : input) {
std::cout << x << '\n';
}
}
int main() {
// Emulates file
std::stringstream ss_error_code("1 2 3\n4 5 6\n7 8 9\n");
test_error_code(ss_error_code);
std::stringstream ss_exception("1 2 3\n4 5 6\n7 8 9\n");
test_exception(ss_exception);
}
Run Code Online (Sandbox Code Playgroud)
输出:
发现错误!
捕获错误: basic_ios::clear
恕我直言,这是一个很好的例子,为什么在绝大多数情况下异常优于结果代码,并且应该将它们用作默认值。
| 归档时间: |
|
| 查看次数: |
743 次 |
| 最近记录: |