我可以为在 std::map 中插入 2 对的函数提供强有力的保证吗?
Can I offer strong guarantee to a function inserting 2 pairs in a std::map?
我想为如下所示的函数提供强有力的保证:
if(condition) {
myMap.insert(key, val);
}
myMap.insert(anotherKey, anotherVal);
标准说 insert
提供了强有力的保证。我的问题是我不知道如何处理第二个 insert
失败的情况。 myMap
已经修改了,所以只提供基本保障。
如果第二次插入时出现异常,捕获异常,删除第一个插入的元素,然后重新抛出。
// insert/emplace returns pair<iterator, bool>
auto insert_result = condition ? myMap.emplace(key, val)
: std::make_pair(myMap.end(), false);
try {
myMap.emplace(anotherKey, anotherVal);
} catch (...) {
if (insert_result.second) {
myMap.erase(insert_result.first);
}
throw;
}
请注意,这仅在 erase
不抛出时有效。幸运的是,该标准在相当温和的假设下保证了这一点:
For associative containers, no clear()
function throws an exception. erase(k)
does not throw an exception unless that exception is thrown by the container’s Compare
object (if any).
(C++11 中的[associative.reqmts.except]/1)
所以只要确保你的比较永远不会抛出错误,这应该有效。
我想为如下所示的函数提供强有力的保证:
if(condition) {
myMap.insert(key, val);
}
myMap.insert(anotherKey, anotherVal);
标准说 insert
提供了强有力的保证。我的问题是我不知道如何处理第二个 insert
失败的情况。 myMap
已经修改了,所以只提供基本保障。
如果第二次插入时出现异常,捕获异常,删除第一个插入的元素,然后重新抛出。
// insert/emplace returns pair<iterator, bool>
auto insert_result = condition ? myMap.emplace(key, val)
: std::make_pair(myMap.end(), false);
try {
myMap.emplace(anotherKey, anotherVal);
} catch (...) {
if (insert_result.second) {
myMap.erase(insert_result.first);
}
throw;
}
请注意,这仅在 erase
不抛出时有效。幸运的是,该标准在相当温和的假设下保证了这一点:
For associative containers, no
clear()
function throws an exception.erase(k)
does not throw an exception unless that exception is thrown by the container’sCompare
object (if any).
(C++11 中的[associative.reqmts.except]/1)
所以只要确保你的比较永远不会抛出错误,这应该有效。