[英]Continue in range based for loop after exception
我有以下程序遍歷目錄並可以捕獲異常:
#include <iostream>
#include <filesystem>
#include <exception>
int main() {
const std::filesystem::path md("/");
try {
for(auto const& dir : std::filesystem::recursive_directory_iterator(md)) {
std::cout << dir.path() << std::endl;
}
}
catch(const std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
return 0;
}
問題是,每當拋出異常時,它都會退出 for 循環並結束程序。 有什么方法可以將 go 返回到 position 處理異常后 for 循環停止的地方?
編輯:錯誤是由 for 循環 recursive_directory_iterator 引起的,而不是來自循環內部。 保證每次在循環中的同一個 position 處拋出相同的錯誤,所以我需要在拋出錯誤后繼續在 position 處循環。
即使您手動編寫循環, std::filesystem::recursive_directory_iterator
也不能完全滿足您的需求。
迭代器可以在兩個地方拋出異常1 ,解除引用運算符 ( *it
) 和遞增運算符 ( ++it
)。
如果其中任何一個報告錯誤(即,在您的情況下拋出異常),則無法再使用迭代器。 2個
對於取消引用迭代器,您可以備份迭代器並跳過無效條目
auto it = std::filesystem::recursive_directory_iterator{md};
while (it != std::filesystem::recursive_directory_iterator{}) {
const auto tmp_it = it;
try {
const auto& path = *tmp_it;
// use path...
}
catch (std::filesystem::filesystem_error const&) {
}
// you can still increment it here
++it;
}
不幸的是,如果增量運算符報告錯誤(拋出或報告std::error_code
),您無法簡單地“跳過”該元素——您可以處理某些情況,但不是所有情況,例如
std::error_code ec;
const auto backup = it;
// try increment
it.increment(ec);
// failed
if (ec) {
it = backup;
// the iterator tried to enter a directory and failed, disable the
// recursion for the next entry
if (it.recursion_pending()) {
it.disable_recursion_pending();
// try again
it.increment(ec);
}
}
// still failed, or was not recursion_pending()
if (ec) {
it = backup;
// try to skip the remaining entry at the given depth go back to
// the parent
it.pop(ec);
}
// nothing much you can do here unfortunately
if (ec) {
}
1構造函數也可以報告錯誤,但在這種情況下,您甚至沒有一個有效的迭代器開始,因此這與您的問題無關。
2標准報價:
[文件系統#fs.class.directory.iterator.general-3]
如果
directory_iterator
類型的迭代器報告錯誤或前進超過最后一個目錄元素,則該迭代器應等於結束迭代器值。 [..]
[文件系統#fs.class.rec.dir.itr.general-3]
除非另有說明,否則
recursive_directory_iterator
的行為與directory_iterator
相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.