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