0

晚上好,

解决方案:问题来自我的分配器中的显式关键字。

编辑:我终于能够找到问题所在。当它与一些自定义分配器一起使用时,它似乎来自 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;
        };
4

1 回答 1

0

因为,不幸的是,你的两个容器是不同的类型。因此,它们的迭代器也是如此。这个问题是 SCARY 迭代器旨在解决的问题 - 当容器应该被认为是等效的迭代目的时,即使它们的类型是不同的。解决方法是统一您的容器类型(可能从另一个派生),或者重写为不依赖基于迭代器的算法(分别取消引用和复制元素)。

编辑: 我能够用一个简单的例子来重现,这与 insert() 调用无关,而是临时 kSet 的右值移动 ctor。使用 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;
};
于 2013-04-29T20:59:13.103 回答