在C++为矢量编写自定义虚拟分配器时遇到问题
Trouble writing custom dummy allocator for vector in C++
我正在尝试为vector<>
编写一个简单的虚拟分配器,以便我可以将vector<>
用作堆栈数组的包装器,如下所示:
#include <vector>
#include "stdio.h"
#include "stack_allocator.h"
using namespace std;
int main() {
int buffer[100];
vector<int, StackAllocator<int>> v((StackAllocator<int>(buffer, 100)));
v.push_back(2);
printf("%d", v[0]);
v.pop_back();
}
我编写了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:UsersmathuDesktopStackVectorx64ReleaseStackVector.exe : fatal error LNK1120: 6 unresolved externals
这是我的代码:
stack_allocator.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;
};
}
stack_allocator.cpp:
#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();
}
}
我很抱歉发布了很多代码,但我真的不知道问题可能在哪里。任何人都可以发现问题所在吗?
因为模板类只能在头文件中实现。阅读以下内容:为什么模板只能在头文件中实现?
相关文章:
- 虚拟决赛作为安全
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 如何在C++中获得"静态纯虚拟"功能?
- C++无法定义虚拟函数 OUTER 类和头文件
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 将 std::allocate_shared 与多态资源分配器一起使用
- 尝试将lambda函数放在队列中时出现一般分配器错误(可能是与unique_ptr有关的错误)
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 大小虚拟继承中的派生类
- 链接器找不到在虚拟类 c++ 中访问的静态字段的符号
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- 使用 C++ 和 i2c 工具从虚拟 i2c 写入和读取
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如果整个应用程序是虚拟映射的,为什么 new 会进行系统调用?
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 在C++为矢量编写自定义虚拟分配器时遇到问题
- 传递给std::basic_string的分配器是否可以使其方法为虚拟的