![](/img/trans.png)
[英]Insert or update into an unordered_map without requiring a default constructor
[英]Insert in unordered map calls constructor
為了避免元素重復,我正在構建一個類,其中包含元素並為其提供訪問權限。
我的元素( DynLibrary
)是可移動的,但不可復制
class DynLibrary
{
public:
DynLibrary() : _handle(nullptr) {}
DynLibrary(const std::string& path) { DynLibrary::open(path); }
DynLibrary(const DynLibrary&) = delete;
DynLibrary(DynLibrary&&) = default;
~DynLibrary() { DynLibrary::close(); }
...
}
這些對象在unordered_map
中分配,該鍵是生成它們的路徑。 我這樣分配他們
class DynAllocator
{
public:
DynLibrary& library(const std::string& f)
{
if (_handles.find(f) == _handles.end())
{
std::cout << "@Emplace" << std::endl;
_handles.emplace(f, DynLibrary(f));
}
std::cout << "@Return" << std::endl;
return _handles.at(f);
}
private:
std::unordered_map<std::string, DynLibrary> _handles;
};
但是,當調用DynAllocator::library
我得到以下輸出:
@Emplace
close 0x1dfd1e0 // DynLibrary destructor
@Return
這意味着插入的對象已經以某種方式被復制,並且復制的析構函數使我的對象無效(使用處理程序調用dlclose
)
DynLibrary
可移動但不可復制的方法DynLibrary
嗎? unordered_map
沒有副本,如何插入DynLibrary
實例? 請注意,我知道如何使用指針/智能指針( std::unique_ptr
)來做到這一點,但我想不惜一切代價避免使用它們!
這意味着插入的對象已經以某種方式被復制,並且復制的析構函數使我的對象無效
不,那不是什么意思。 DynLibrary
具有delete
d復制構造函數,因此,如果通過過載解析以某種方式選擇該構造函數,則該代碼將無法編譯。
_handles.emplace(f, DynLibrary(f));
上面一行發生的事情是您正在創建一個臨時的DynLibrary
對象,然后將其構造為unordered_map
。 如果希望避免這種移動構造,請改用std::piecewise_construct
。
_handles.emplace(std::piecewise_construct,
std::forward_as_tuple(f),
std::forward_as_tuple(f));
現在,您將直接在unordered_map
構造DynLibrary
對象,並繞過臨時對象的創建。
正如TC所評論的 ,在這種情況下,分段構造構造函數不是必需的,因為DynLibrary
具有非explicit
轉換構造函數。 您可以使用以下方法達到與上述相同的效果
_handles.emplace(f, f);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.