考慮到以下簡化代碼是Cache :: operator []的調用者保證接收映射值的副本?參考C++複製elision
#include <string>
#include <map>
#include <mutex>
#include <iostream>
class Cache {
public:
std::string operator[] (int k) {
std::lock_guard<std::mutex> lock(m_mutex);
if (! m_map.count(k)) m_map[k] = "Hello world";
return m_map[k];
}
private:
std::mutex m_mutex;
std::map<int, std::string> m_map;
};
int main (int argc, char *argv[]) {
Cache c;
auto v = c[42];
std::cout << v << std::endl;
return 0;
}
可以看出我的意圖是併發和互斥映射值的繼續存在,不能保證釋放後。
std::map<>::operator[]
返回參考std::string&
。我的理解是,複製結構會產生一個無名的臨時文件,然後可能會受RVO影響。
何時將複製elision發生,並可能導致不同的線程返回相同的對象,而不是自己的副本?如果是的話,如何避免這種情況?
實際的代碼涉及填充緩存的數據庫查找,映射鍵是表主鍵,映射值是從行字段構造的對象。
你的代碼沒問題。 – inf
@inf謝謝。所以,如果我明白正確地更改'Cache :: operator [](int)'返回一個引用('std :: string&')打破所需的併發? – patchsoft
是的,因爲那時用戶可以通過參考而不是副本直接訪問。 – inf