使用自定义分配器的Std::unordered_set
std::unordered_set with custom allocator
晚上好
解决方案:问题来自于我的分配器的显式关键字。
编辑:我终于找到了问题所在。它似乎来自unordered_set的move函数,当它与一些自定义分配器一起使用时。还挖。
编辑:奇怪的是,当使用我的自定义分配器和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.0vcincludeunordered_set 195 1
请注意,如果我不放入kSet.insert(),我不会得到错误。
类型定义是在CProfiler的范围内完成的。
我已经被困了好几天了,它似乎不像人们想象的那样来自hasher。任何想法都是欢迎的,很抱歉,如果这篇文章不是很好,因为这是我在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;
};
因为,不幸的是,您的两个容器是不同的类型。因此,它们的迭代器也是如此。这个问题正是吓人迭代器的设计目的——当容器应该被视为迭代目的的等效时,即使它们的类型不同。解决方法是统一容器类型(可能从另一个容器类型派生),或者重写以不依赖于基于迭代器的算法(分别解引用和复制元素)。
编辑:我能够用一个简单的示例进行再现,该示例与insert()调用无关,而是与临时kSet的右值移动函数有关。在c++ 11中,对自定义分配器有一些新的要求——特别是重新绑定类型函数。更多信息请看这里
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;
};
相关文章:
- 为什么我无法更改"set<set>"循环中的值<int>
- 对于set上的循环-获取next元素迭代器
- 在声明中合并两个常量"std::set"(不是在运行时)
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将 std::set 与基于键的比较器一起使用
- 如何使用set实现无序数据结构?
- 使用运算符调用 void 函数时出错<set>
- 修改"std::set"中用户定义类型的值
- 生成提升::hana::set 的常量表达式问题
- 如何在构造函数参数中初始化"std::set"?
- 如何使用 lower_bound/upper_bound 从 std::set 获取索引号?
- 如何在 C++ 中转发声明 std::set?
- 重构使用动态强制转换的 std::set 的比较运算符
- set::find 查找不存在的元素
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- 将 std:set<int32_t> 复制到 std::set <uint32_t>的好方法
- 错误 C2676:std::set::const_iterator 没有运算符 + 函数?
- std::set 是否将对象连续存储在内存中?
- 是否有一个 std::set 函数来确定不超过数字 x 的最大元素?
- google test PrintTo for std::set<std::string>