晚上好,
解决方案:问题来自我的分配器ctors的显式关键字。
编辑:我终于找到了问题所在。当它与一些自定义分配器一起使用时,似乎来自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;
};
答案 0 :(得分:0)
因为,不幸的是,你的两个容器是不同的类型。因此,他们的迭代器也是如此。这个问题是SCARY迭代器旨在解决的问题 - 当容器被认为是等效的迭代目的时,即使它们的类型是不同的。解决方法是统一容器类型(可能从另一个派生类型),或者重写不依赖于基于迭代器的算法(单独取消引用和复制元素)。
修改强> 我能够用一个简单的例子重新编写,它与insert()调用无关,而是与临时kSet的rvalue移动ctor无关。使用C ++ 11,您的自定义分配器有一些新要求 - 特别是重新绑定类型函数。有关详细信息,请参阅here。
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;
};