簡體   English   中英

帶有自定義分配器的std :: unordered_set

[英]std::unordered_set with custom allocator

晚上好,

解決方案:問題來自我的分配器控制器的顯式關鍵字。

編輯:我終於能夠找到問題。 與某些自定義分配器一起使用時,它似乎來自unordered_set的移動ctor。 還在挖。

編輯:奇怪的是,使用我的自定義分配器和std :: vector時沒有問題。

嘗試從中復制元素時,為什么會收到錯誤消息:

typedef std::unordered_set< const CScopeProfiler* > CInternalScopeProfilersSet;

至 :

typedef std::unordered_set< const CScopeProfiler*, std::hash< const CScopeProfiler* >, std::equal_to< const CScopeProfiler* >, CAllocator< const CScopeProfiler* > > CScopeProfilersSet;

如下 :

CProfiler::CScopeProfilersSet CProfiler::ScopeProfilersRegistry() const
{
    CScopeProfilersSet kSet;

    kSet.insert( *( m_pkRegister->begin() ) );

    return kSet;
}

確切的錯誤消息以法語給出,因此近似翻譯為:

Error 1 error C2664: 'std::_Hash<_Traits>::_Hash(const std::_Uhash_compare<_Kty,_Hasher,_Keyeq> &,const GameForge::Core::CAllocator<T> &)' : impossible to convert second parameter of 'std::_Wrap_alloc<_Alloc>' to 'const GameForge::Core::CAllocator<T> &'   c:\program files (x86)\microsoft visual studio 11.0\vc\include\unordered_set    195 1

請注意,如果我不放置kSet.insert(),則不會收到該錯誤。

typedef在CProfiler的范圍內完成。

我已經被困了好幾天了,它似乎並沒有像人們期望的那樣來自哈希器。 歡迎提出任何想法,如果這篇文章的格式不正確,這是我第一次在StackOverflow上發表,抱歉。

PS:這里是代碼段的要求。

namespace GameForge
{
    namespace Core
    {
        class CAllocationsHistogram;

        // Ensure profiling code isn't profiled.
        class GF_API CProfiler
        {
        public:
            class CScopeRun;

            class GF_API CScopeProfiler
            {
                friend CProfiler;
                friend CScopeRun;

            public:
                CScopeProfiler( const char* pcLabel );
                ~CScopeProfiler();
            };

            class GF_API CScopeRun
            {
                friend CProfiler;

            public:
                CScopeRun( CScopeProfiler& rkScopeProfiler );
                ~CScopeRun();
            };

            typedef std::unordered_set< const CScopeProfiler*,
                                        std::hash< const CScopeProfiler* >,
                                        std::equal_to< const CScopeProfiler* >,
                                        CAllocator< const CScopeProfiler* > > CScopeProfilersSet;

        private:
            typedef std::unordered_set< const CScopeProfiler* > CInternalScopeProfilersSet;

        public:
            CScopeProfilersSet ScopeProfilersRegistry() const;

        protected:
            CProfiler();
            ~CProfiler();

        private:
            CInternalScopeProfilersSet* m_pkRegister;
        };

因為不幸的是,您的兩個容器是不同的類型。 因此,它們的迭代器也是如此。 這個問題是SCARY迭代器旨在解決的問題-當出於迭代目的應將容器視為等效時,即使它們的類型不同。 解決方法是要么統一您的容器類型(可能是從另一個容器派生),要么重寫它而不依賴於基於迭代器的算法(分別引用和復制元素)。

編輯:我能夠用一個簡單的示例進行復制,該示例與insert()調用無關,而只是臨時kSet的右值移動ctor。 使用C ++ 11,自定義分配器有一些新要求-特別是rebind類型函數。 有關更多信息,請參見此處

template<typename T>
struct CAllocator : allocator<T>
{
    CAllocator(){}

    template <class U>
    CAllocator(CAllocator<U> const &) {}

    // This required to ensure custom allocator is propagated in move semantics
    template <class U>
    struct rebind
    {
        typedef CAllocator<U> other;
    };
};

typedef std::unordered_set< const CScopeProfiler*, std::hash< const CScopeProfiler* >, std::equal_to< const CScopeProfiler* >, CAllocator< const CScopeProfiler * > >  CScopeProfilersSet;

CScopeProfilersSet ScopeProfilersRegistry()
{
    CScopeProfilersSet kSet;
    return kSet;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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