class foo {
std::vector<int> datas;
public:
template <typename It>
foo(It x, It y) {
for(; x != y; ++x)
insert(*x);
}
void insert(int val) {
if(val == 5)
throw 99;
else
datas.push_back(val);
}
void print() const {
for(int x : datas)
std::cout << x << " ";
}
};
int main() {
std::vector<int> v{1, 2, 3, 5, 6, 7};
foo* f;
try {
f = new foo(std::begin(v), std::end(v));
}catch(int const& x) {
}
f->print();
}
我想在这种情况下不会构造f;在foo构造函数的主体中不处理insert方法抛出的异常。 我在gcc 8.2.0上得到以下输出: 1 2 3 5 6 7
答案 0 :(得分:4)
我想在这种情况下不会构造f;
在这种情况下,不会构造foo
实例。
此外,f
不会被分配给它,因此其值将保持不确定。
这是正确的行为吗?
通过不确定的指针间接访问对象具有不确定的行为。
答案 1 :(得分:0)
虽然已经讨论了不确定的性质,但我认为调查实际产生的结果并推测为什么会看到它可能很有趣。
尽管我没有证据,但我相信这是编译器优化和代码推理的有趣结果。我们看到输出是1 2 3 5 6 7
,即使代码中有元素throw
的{{1}}语句也是如此。怎么会这样?
在我看来,由于我们在5
块之外有f->print()
,所以编译器会认为try
从未被初始化-因此构造函数从不会抛出。由于构造函数不会抛出异常,因此f
永远不会成立!因此,分支被删除。这样我们就得到了结果。