簡體   English   中英

異常后繼續基於范圍的for循環

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM