使用自定义分配器模板定义STL容器的静态大小

时间:2014-08-09 21:04:19

标签: c++ visual-studio-2010 templates memory-management stl

我一直致力于一个允许保存和加载进程状态的程序。 为了消除一些内存泄漏,我认为在初始化期间决定STL容器可以包含的项目数是有用的 我的解决方案基于Rebinding in a custom STL allocator with pre-allocated blockSTL Container: Constructor's Allocator parameter and scoped allocators的答案 但是,由于项目定义的限制,仅限于VS2010,我无法利用所有c ++ 11功能。 然而我的适应性有些不对劲,我花了几个星期试图解决它,但我不能,这是我第一次尝试分配器。

当我尝试构建它时,我收到此错误:

error C2664: 'StaticAllocator<T,szSlots>::StaticAllocator(const StaticAllocator<T,szSlots> &) throw()' : cannot convert parameter 1 from 'StaticAllocator<T,szSlots>' to 'const StaticAllocator<T,szSlots> &'

详细输出显示:

error C2664: 'StaticAllocator<T,szSlots>::StaticAllocator(const StaticAllocator<T,szSlots> &) throw()' : cannot convert parameter 1 from 'StaticAllocator<T,szSlots>' to 'const StaticAllocator<T,szSlots> &'
      with
      [
          T=std::_Container_proxy,
          szSlots=2
      ]
      and
      [
          T=int,
          szSlots=2
      ]
      and
      [
          T=std::_Container_proxy,
          szSlots=2
      ]
      Reason: cannot convert from 'StaticAllocator<T,szSlots>' to 'const StaticAllocator<T,szSlots>'
      with
      [
          T=int,
          szSlots=2
      ]
      and
      [
          T=std::_Container_proxy,
          szSlots=2
      ]
      No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

我遗漏了一些东西,但不完全确定实施它的内容或方法。

我的自定义分配器看起来像这样,并且只适用于vector:(StaticAllocator.h)

#pragma once

#include <string.h>
#include <memory>

template <class T, size_t szSlots = 0>
class StaticAllocator
{
private:
    size_t szSlotsAllocated;
    size_t szSlotsInUse;
    size_t szSlotSize;
    T* array;

public:
    typedef T                   value_type;
    typedef value_type*         pointer;
    typedef const value_type*   const_pointer;
    typedef value_type&         reference;
    typedef const value_type&   const_reference;
    typedef std::size_t         size_type;
    typedef std::ptrdiff_t      difference_type;

    StaticAllocator()
    {
        if(szSlots > 0) array = new T(szSlots);
        szSlotsAllocated = szSlots;
        szSlotsInUse = 0;
        szSlotSize = sizeof(T);
    }

    StaticAllocator(const StaticAllocator& alloc) throw()
    {
        if(alloc.szSlotsAllocated > 0)
        {
            array = new T[alloc.szSlotsAllocated];
            memcpy(array, alloc.array, alloc.szSlotsAllocated * alloc.szSlotSize);
        }
        szSlotsAllocated = alloc.szSlotsAllocated;
        szSlotsInUse = alloc.szSlotsInUse;
        szSlotSize = alloc.szSlotSize;
    }

    template<class U>
    StaticAllocator(const StaticAllocator<U>& alloc) throw()
    {
        // Pray?
        if(alloc.szSlotsAllocated > 0)
        {
            (U*)array = new U(alloc.szSlotsAllocated);
            memcpy(array, alloc.array, alloc.szSlotsAllocated * alloc.szSlotSize);
        }
        szSlotsAllocated = alloc.szSlotsAllocated;
        szSlotsInUse = alloc.szSlotsInUse;
        szSlotSize = alloc.szSlotSize;
    }

    ~StaticAllocator()
    {
        if(szSlotsAllocated > 0) delete [] array;
    }    

    template<class U>
    struct rebind
    {
        typedef StaticAllocator<U, szSlots> other;
    };

    pointer address(reference x) const
    {
        return &x;
    }
    const_pointer address(const_reference x) const
    {
        return &x;
    }

    pointer allocate (size_type n, const_pointer hint = 0)
    {
        if((szSlotsInUse + n) < szSlotsAllocated)
        {
            pointer rv = &(array[szSlotsInUse]);
            szSlotsInUse += n;
            return rv;
        }
        throw std::bad_alloc();
    }

    void deallocate (pointer p, size_type n)
    {
        if((szSlotsInUse - n) < 0) szSlotsInUse = 0;
        else szSlotsInUse -= n;
    }

    size_type max_size() const throw()
    {
        return szSlotsAllocated;
    }

    void construct (pointer p, const_reference val)
    {
        p = value_type(val); // Can memcpy be used instead? (memcpy(p, val, szSlotSize);)
    }

    void destroy (pointer p)
    {
        p->~value_type();
    }
};

导致编译错误的演示程序:

#include <stdio.h>
#include <vector>

#include "StaticAllocator.h"

int main(void)
{
    std::vector<int, StaticAllocator<int, 2>> iVec;
    iVec.push_back(3);
    iVec.push_back(5);

    printf("contents: %i and %i.\n", iVec[0], iVec[1]);
    return 0;
}

感谢您提前提供任何帮助。

0 个答案:

没有答案