簡體   English   中英

插入無序地圖調用構造函數

[英]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.

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