簡體   English   中英

盡管右側有異常,但仍發生C ++中的賦值

[英]Assignment in C++ occurs despite exception on the right side

我有一些(C ++ 14)代碼看起來像這樣:

map<int, set<string>> junk;
for (int id : GenerateIds()) {
    try {
        set<string> stuff = GetStuff();
        junk[id] = stuff;
    } catch (const StuffException& e) {
        ...
    }
}

這可行。 有時GetStuff()會引發一個異常,該異常可以正常工作,因為如果發生異常,那么我就不需要垃圾映射中的值。

但是起初我是在循環中編寫此代碼的,這是行不通的:

junk[id] = GetStuff();

更准確地說,即使GetStuff()引發異常,也會創建junk[id] (並分配一個空集)。

這不是我期望的:我希望它們以相同的方式起作用。

這里有我誤解的C ++原理嗎?

在C ++ 17之前,賦值運算符的左側和右側之間沒有順序。

在C ++ 17中,首先引入了顯式排序(首先評估了右側)。

這意味着未指定評估順序,這取決於實現以所需的順序執行評估,在這種情況下,它將首先評估左側。

有關更多詳細信息,請參見此評估訂單參考 (尤其是要點20)。

std :: map :: operator []

返回對該值的引用,該值映射到與鍵等效的鍵,如果該鍵尚不存在,則執行插入。

junk[id]導致上述插入,此后已經發生GetStuff()拋出。 請注意,在C ++ 14中,發生這些事情的順序是由實現定義的,因此使用其他編譯器,您的junk[id] = GetStuff(); 如果GetStuff()拋出,則可能不會執行插入GetStuff()

您誤解了operator[]std::map

它返回對映射項的引用。 因此,您的代碼首先是在該位置插入默認項,然后調用operator=設置新值。

要按照您期望的方式工作,您需要使用std::map::insert (*):

junk.insert(std::make_pair(id, GetStuff()));

注意 :如果id尚未映射,則insert將僅添加值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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