![](/img/trans.png)
[英]C++ comparison with an assignment expression be the right hand side expression
[英]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.