C++ 在C+;中为向量编写自定义虚拟分配器时出现问题+;

C++ 在C+;中为向量编写自定义虚拟分配器时出现问题+;,c++,vector,allocator,C++,Vector,Allocator,我正在尝试为vector编写一个简单的虚拟分配器,以便使用vector作为堆栈数组的包装器,如下所示: #包括 #包括“stdio.h” #包括“stack_allocator.h” 使用名称空间std; int main(){ int缓冲区[100]; 向量v((StackAllocator(buffer,100)); v、 推回(2); printf(“%d”,v[0]); v、 向后弹出(); } 我编写了StackAllocator类,但我在Visual Studio中遇到了链接器错误

我正在尝试为
vector
编写一个简单的虚拟分配器,以便使用
vector
作为堆栈数组的包装器,如下所示:

#包括
#包括“stdio.h”
#包括“stack_allocator.h”
使用名称空间std;
int main(){
int缓冲区[100];
向量v((StackAllocator(buffer,100));
v、 推回(2);
printf(“%d”,v[0]);
v、 向后弹出();
}
我编写了
StackAllocator
类,但我在Visual Studio中遇到了链接器错误,不幸的是,这些错误非常普遍:

1> main.cpp
1> main.obj: error LNK2001: unresolved external symbol "public: void __cdecl std::StackAllocator<int,class std::allocator<int> >::destroy<int>(int *)" (??$destroy@H@?$StackAllocator@HV?$allocator@H@std@@@std@@QEAAXPEAH@Z)
1> main.obj: error LNK2001: unresolved external symbol "public: void __cdecl std::StackAllocator<int,class std::allocator<int> >::construct<int,int>(int *,int &&)" (??$construct@HH@?$StackAllocator@HV?$allocator@H@std@@@std@@QEAAXPEAH$$QEAH@Z)
1> main.obj: error LNK2001: unresolved external symbol "public: unsigned __int64 __cdecl std::StackAllocator<int,class std::allocator<int> >::max_size(void)const " (?max_size@?$StackAllocator@HV?$allocator@H@std@@@std@@QEBA_KXZ)
1> main.obj: error LNK2001: unresolved external symbol "public: void __cdecl std::StackAllocator<int,class std::allocator<int> >::deallocate(int *,unsigned __int64)" (?deallocate@?$StackAllocator@HV?$allocator@H@std@@@std@@QEAAXPEAH_K@Z)
1> main.obj: error LNK2001: unresolved external symbol "public: int * __cdecl std::StackAllocator<int,class std::allocator<int> >::allocate(unsigned __int64,void const *)" (?allocate@?$StackAllocator@HV?$allocator@H@std@@@std@@QEAAPEAH_KPEBX@Z)
1> main.obj: error LNK2001: unresolved external symbol "public: __cdecl std::StackAllocator<int,class std::allocator<int> >::StackAllocator<int,class std::allocator<int> >(int *,unsigned __int64,class std::allocator<int> const &)" (??0?$StackAllocator@HV?$allocator@H@std@@@std@@QEAA@PEAH_KAEBV?$allocator@H@1@@Z)
1> C:\Users\mathu\Desktop\StackVector\x64\Release\StackVector.exe : fatal error LNK1120: 6 unresolved externals
1>main.cpp
1> main.obj:错误LNK2001:未解析的外部符号“public:void u cdecl std::StackAllocator::destroy(int*)”(?)$destroy@H@?$StackAllocator@HV?$allocator@H@std@@@std@@QEAAXPEAH@Z)
1> main.obj:错误LNK2001:未解析的外部符号“public:void\uu cdecl std::StackAllocator::construct(int*,int&)”($construct@HH@?$StackAllocator@HV?$allocator@H@std@@@std@@QEAAXPEAH$$QEAH@Z)
1> main.obj:错误LNK2001:未解析的外部符号“public:unsigned_uint64_ucdecl std::StackAllocator::max_size(void)const”(?max_size@)$StackAllocator@HV?$allocator@H@std@@@std@@@QEBA_KXZ)
1> main.obj:错误LNK2001:未解析的外部符号“public:void\uu cdecl std::StackAllocator::deallocate(int*,unsigned\uu int64)”(?deallocate@$StackAllocator@HV?$allocator@H@std@@@std@@QEAAXPEAH_K@Z)
1> main.obj:错误LNK2001:未解析的外部符号“public:int*uu cdecl std::StackAllocator::allocate(unsigned uu int64,void const*)”(?allocate@$StackAllocator@HV?$allocator@H@std@@@std@@@QEAAPEAH_KPEBX@Z)
1> main.obj:错误LNK2001:未解析的外部符号“public:u cdecl std::StackAllocator::StackAllocator(int*,无符号uu int64,类std::allocator const&”)(?0$StackAllocator@HV?$allocator@H@std@@@std@@QEAA@PEAH_KAEBV?$allocator@H@1@@Z)
1> C:\Users\mathu\Desktop\StackVector\x64\Release\StackVector.exe:致命错误LNK1120:6个未解析的外部
这是我的密码:

堆栈分配器.h:

#pragma once

#include <functional>

namespace std {
    template <typename T, typename Allocator = std::allocator<T>>
    class StackAllocator {
    public:
        typedef typename allocator_traits<Allocator>::value_type value_type;
        typedef typename allocator_traits<Allocator>::pointer pointer;
        typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
        typedef typename allocator_traits<Allocator>::size_type size_type;
        typedef typename allocator_traits<Allocator>::difference_type difference_type;
        typedef typename allocator_traits<Allocator>::const_void_pointer const_void_pointer;
        typedef typename Allocator::reference reference;
        typedef typename Allocator::const_reference const_reference;

        template<typename T2>
        struct rebind {
            typedef StackAllocator<T2> other;
        };

    private:
        size_t m_size;
        Allocator m_allocator;
        pointer m_begin;
        pointer m_end;
        pointer m_stack_pointer;

        bool pointer_to_internal_buffer(const_pointer p) const;

    public:
        StackAllocator(const Allocator& alloc = Allocator());
        StackAllocator(pointer buffer, size_t size, const Allocator& alloc = Allocator());
        template <typename T2>
        StackAllocator(const StackAllocator<T2, Allocator>& other);
        pointer allocate(size_type n, const_void_pointer hint = const_void_pointer());
        void deallocate(pointer p, size_type n);
        size_type capacity() const;
        size_type max_size() const noexcept;
        pointer address(reference x) const noexcept;
        const_pointer address(const_reference x) const noexcept;
        pointer buffer() const noexcept;

        template <typename T2, typename... Args>
        void construct(T2* p, Args&&... args);

        template <typename T2>
        void destroy(T2* p);

        template <typename T2>
        bool operator==(const StackAllocator<T2, Allocator>& other) const noexcept;

        template <typename T2>
        bool operator!=(const StackAllocator<T2, Allocator>& other) const noexcept;
    };
}
#include "stack_allocator.h"

namespace std {
#define AllocatorTemplate template <typename T, typename Allocator>
#define StackAlloc StackAllocator<T, Allocator>

    AllocatorTemplate StackAlloc::StackAllocator(const Allocator& alloc) :
        m_size(0),
        m_allocator(alloc),
        m_begin(nullptr),
        m_end(nullptr),
        m_stack_pointer(nullptr) {
    }

    AllocatorTemplate StackAlloc::StackAllocator(pointer buffer, size_t size, const Allocator& alloc) :
        m_size(size),
        m_allocator(alloc),
        m_begin(buffer),
        m_end(buffer + size),
        m_stack_pointer(buffer) {
    }

    AllocatorTemplate template <typename T2> StackAlloc::StackAllocator(const StackAllocator<T2, Allocator>& other) :
        m_size(other.m_size),
        m_allocator(other.m_allocator),
        m_begin(other.m_begin),
        m_end(other.m_end),
        m_stack_pointer(other.m_stack_pointer) {
    }

    AllocatorTemplate typename StackAlloc::size_type StackAlloc::capacity() const {
        return m_size;
    }

    AllocatorTemplate typename StackAlloc::pointer StackAlloc::allocate(size_type n, const_void_pointer hint) {
        if (n <= size_type(distance(m_stack_pointer, m_end))) {
            pointer result = m_stack_pointer;
            m_stack_pointer += n;
            return result;
        }
        else
            return m_allocator.allocate(n, hint);
    }

    AllocatorTemplate void StackAlloc::deallocate(pointer p, size_type n) {
        if (pointer_to_internal_buffer(p))
            m_stack_pointer -= n;
        else
            m_allocator.deallocate(p, n);
    }

    AllocatorTemplate typename StackAlloc::size_type StackAlloc::max_size() const noexcept {
        return m_size();
    }

    AllocatorTemplate template <typename T2, typename... Args> void StackAlloc::construct(T2* p, Args&&... args) {
        m_allocator.construct(p, forward<Args>(args)...);
    }

    AllocatorTemplate template <typename T2> void StackAlloc::destroy(T2* p) {
        m_allocator.destroy(p);
    }

    AllocatorTemplate typename StackAlloc::pointer StackAlloc::address(reference x) const noexcept {
        if (pointer_to_internal_buffer(addressof(x)))
            return addressof(x);
        else
            return m_allocator.address(x);
    }

    AllocatorTemplate typename StackAlloc::const_pointer StackAlloc::address(const_reference x) const noexcept {
        if (pointer_to_internal_buffer(addressof(x)))
            return addressof(x);
        else
            return m_allocator.address(x);
    }

    AllocatorTemplate typename StackAlloc::pointer StackAlloc::buffer() const noexcept {
        return m_begin;
    }

    AllocatorTemplate bool StackAlloc::pointer_to_internal_buffer(const_pointer p) const {
        return (!(less<const_pointer>()(p, m_begin)) && (less<const_pointer>()(p, m_end)));
    }

    AllocatorTemplate template <typename T2> bool StackAlloc::operator==(const StackAllocator<T2, Allocator>& other) const noexcept {
        return buffer() == other.buffer();
    }

    AllocatorTemplate template <typename T2> bool StackAlloc::operator!=(const StackAllocator<T2, Allocator>& other) const noexcept {
        return buffer() != other.buffer();
    }
}
#pragma一次
#包括
名称空间标准{
模板
类堆栈分配器{
公众:
typedef typename分配器\特征::值\类型值\类型;
typedef typename分配器_traits::指针;
typedef typename分配器_traits::const_指针const_指针;
typedef typename分配器\特征::大小\类型大小\类型;
typedef typename分配器_traits::difference_type difference_type;
typedef typename分配器_traits::const_void_指针const_void_指针;
typedef typename分配器::引用引用;
typedef typename分配器::const_reference const_reference;
模板
结构重新绑定{
类型定义堆栈分配器其他;
};
私人:
大小;
分配器m_分配器;
指针m_开始;
指针m_端;
指针m_堆栈_指针;
布尔指针指向内部缓冲区(常量指针p)常量;
公众:
StackAllocator(常量分配器&alloc=Allocator());
StackAllocator(指针缓冲区、大小、常量分配器&alloc=Allocator());
模板
堆栈分配器(常量堆栈分配器和其他);
指针分配(大小\类型n,常数\无效\指针提示=常数\无效\指针());
无效解除分配(指针p,大小\类型n);
大小\类型容量()常数;
size_type max_size()常量noexcept;
指针地址(参考x)常量noexcept;
常量指针地址(常量引用x)常量noexcept;
指针缓冲区()const noexcept;
模板
无效构造(T2*p,Args&…Args);
模板
空洞破坏(T2*p);
模板
bool运算符==(常量StackAllocator和其他)常量noexcept;
模板
布尔运算符!=(常量堆栈分配器和其他)常量noexcept;
};
}
堆栈分配器.cpp:

#pragma once

#include <functional>

namespace std {
    template <typename T, typename Allocator = std::allocator<T>>
    class StackAllocator {
    public:
        typedef typename allocator_traits<Allocator>::value_type value_type;
        typedef typename allocator_traits<Allocator>::pointer pointer;
        typedef typename allocator_traits<Allocator>::const_pointer const_pointer;
        typedef typename allocator_traits<Allocator>::size_type size_type;
        typedef typename allocator_traits<Allocator>::difference_type difference_type;
        typedef typename allocator_traits<Allocator>::const_void_pointer const_void_pointer;
        typedef typename Allocator::reference reference;
        typedef typename Allocator::const_reference const_reference;

        template<typename T2>
        struct rebind {
            typedef StackAllocator<T2> other;
        };

    private:
        size_t m_size;
        Allocator m_allocator;
        pointer m_begin;
        pointer m_end;
        pointer m_stack_pointer;

        bool pointer_to_internal_buffer(const_pointer p) const;

    public:
        StackAllocator(const Allocator& alloc = Allocator());
        StackAllocator(pointer buffer, size_t size, const Allocator& alloc = Allocator());
        template <typename T2>
        StackAllocator(const StackAllocator<T2, Allocator>& other);
        pointer allocate(size_type n, const_void_pointer hint = const_void_pointer());
        void deallocate(pointer p, size_type n);
        size_type capacity() const;
        size_type max_size() const noexcept;
        pointer address(reference x) const noexcept;
        const_pointer address(const_reference x) const noexcept;
        pointer buffer() const noexcept;

        template <typename T2, typename... Args>
        void construct(T2* p, Args&&... args);

        template <typename T2>
        void destroy(T2* p);

        template <typename T2>
        bool operator==(const StackAllocator<T2, Allocator>& other) const noexcept;

        template <typename T2>
        bool operator!=(const StackAllocator<T2, Allocator>& other) const noexcept;
    };
}
#include "stack_allocator.h"

namespace std {
#define AllocatorTemplate template <typename T, typename Allocator>
#define StackAlloc StackAllocator<T, Allocator>

    AllocatorTemplate StackAlloc::StackAllocator(const Allocator& alloc) :
        m_size(0),
        m_allocator(alloc),
        m_begin(nullptr),
        m_end(nullptr),
        m_stack_pointer(nullptr) {
    }

    AllocatorTemplate StackAlloc::StackAllocator(pointer buffer, size_t size, const Allocator& alloc) :
        m_size(size),
        m_allocator(alloc),
        m_begin(buffer),
        m_end(buffer + size),
        m_stack_pointer(buffer) {
    }

    AllocatorTemplate template <typename T2> StackAlloc::StackAllocator(const StackAllocator<T2, Allocator>& other) :
        m_size(other.m_size),
        m_allocator(other.m_allocator),
        m_begin(other.m_begin),
        m_end(other.m_end),
        m_stack_pointer(other.m_stack_pointer) {
    }

    AllocatorTemplate typename StackAlloc::size_type StackAlloc::capacity() const {
        return m_size;
    }

    AllocatorTemplate typename StackAlloc::pointer StackAlloc::allocate(size_type n, const_void_pointer hint) {
        if (n <= size_type(distance(m_stack_pointer, m_end))) {
            pointer result = m_stack_pointer;
            m_stack_pointer += n;
            return result;
        }
        else
            return m_allocator.allocate(n, hint);
    }

    AllocatorTemplate void StackAlloc::deallocate(pointer p, size_type n) {
        if (pointer_to_internal_buffer(p))
            m_stack_pointer -= n;
        else
            m_allocator.deallocate(p, n);
    }

    AllocatorTemplate typename StackAlloc::size_type StackAlloc::max_size() const noexcept {
        return m_size();
    }

    AllocatorTemplate template <typename T2, typename... Args> void StackAlloc::construct(T2* p, Args&&... args) {
        m_allocator.construct(p, forward<Args>(args)...);
    }

    AllocatorTemplate template <typename T2> void StackAlloc::destroy(T2* p) {
        m_allocator.destroy(p);
    }

    AllocatorTemplate typename StackAlloc::pointer StackAlloc::address(reference x) const noexcept {
        if (pointer_to_internal_buffer(addressof(x)))
            return addressof(x);
        else
            return m_allocator.address(x);
    }

    AllocatorTemplate typename StackAlloc::const_pointer StackAlloc::address(const_reference x) const noexcept {
        if (pointer_to_internal_buffer(addressof(x)))
            return addressof(x);
        else
            return m_allocator.address(x);
    }

    AllocatorTemplate typename StackAlloc::pointer StackAlloc::buffer() const noexcept {
        return m_begin;
    }

    AllocatorTemplate bool StackAlloc::pointer_to_internal_buffer(const_pointer p) const {
        return (!(less<const_pointer>()(p, m_begin)) && (less<const_pointer>()(p, m_end)));
    }

    AllocatorTemplate template <typename T2> bool StackAlloc::operator==(const StackAllocator<T2, Allocator>& other) const noexcept {
        return buffer() == other.buffer();
    }

    AllocatorTemplate template <typename T2> bool StackAlloc::operator!=(const StackAllocator<T2, Allocator>& other) const noexcept {
        return buffer() != other.buffer();
    }
}
#包括“stack_allocator.h”
名称空间标准{
#定义分配器模板模板
#定义StackAlloc StackAllocator
AllocatorTemplate StackAlloc::StackAllocator(常量分配器和alloc):
m_尺寸(0),
m_分配器(alloc),
m_begin(空PTR),
m_端(空PTR),
m_堆栈_指针(nullptr){
}
AllocatorTemplate StackAlloc::StackAllocator(指针缓冲区、大小、常量分配器和alloc):
m_尺寸(尺寸),
m_分配器(alloc),
m_begin(缓冲区),
m_端(缓冲区+大小),
m_堆栈_指针(缓冲区){
}
AllocatorTemplate StackAlloc::StackAllocator(常量StackAllocator和其他):
m_尺寸(其他m_尺寸),
m_分配器(其他.m_分配器),
m_begin(其他.m_begin),
m_端(其他m_端),
m_堆栈指针(其他.m_堆栈指针){
}
AllocatorTemplateTypeName StackAlloc::size\u type StackAlloc::capacity()常量{
返回m_大小;
}
AllocatorTemplateTypeName StackAlloc::指针StackAlloc::allocate(大小\类型n,常量\无效\指针提示){

if(n),因为模板类只能在头文件中实现。
阅读此文:

啊,好吧,我现在感到很尴尬……无论如何,谢谢!虽然这是一个有趣的练习,但我想知道与仅使用
std::array
相比,这样做是否有任何优势。在我开始工作后,我计划让它支持使用alloca()在堆栈上创建的可变长度数组这就是为什么我避免让编译时的大小。VLAS是由GCC在C++中支持的扩展。它们不是标准的C++。完全!!)VisualStudio不支持VLAs,因此我可以使用ApLoad()。在堆栈上分配一个可变长度的缓冲区,并使用这个类将其封装为<代码>向量实例。<代码> ALOLACA也不是标准C++。