这是一个工作代码,但不是推荐的方式。
这段代码有很多痕迹来显示它在做什么。它不检查分配请求的大小是否不超过缓冲区。如有必要,您可以进行此项检查。请注意,std::basic_string 会尝试分配不必要的资源。
#include <string>
#include <iostream>
template<typename T, size_t S>
class fixed_allocator
{
typedef std::allocator<T> _base;
std::ostream& trace() const { return std::cerr << "TRACE fixed_allocator " << (void*)this ; }
public:
typedef typename _base::value_type value_type;
typedef typename _base::pointer pointer;
typedef typename _base::const_pointer const_pointer;
typedef typename _base::reference reference;
typedef typename _base::const_reference const_reference;
typedef typename _base::size_type size_type;
typedef typename _base::difference_type difference_type;
template<class C> struct rebind {
typedef fixed_allocator<C, S*sizeof(C)/sizeof(T)> other;
};
T* buffer_;
fixed_allocator(T* b) : buffer_(b) { trace() << "ctor: p=" << (void*)b << std::endl; }
fixed_allocator() : buffer_(0) { trace() << "ctor: NULL" << std::endl; };
fixed_allocator(const fixed_allocator &that) : buffer_(that.buffer_) { trace() << "ctor: copy " << (void*)buffer_ << " from " << (void*) &that << std::endl; };
pointer allocate(size_type n, std::allocator<void>::const_pointer hint=0) {
trace() << "allocating on stack " << n << " bytes" << std::endl;
return buffer_;
}
bool operator==(const fixed_allocator& that) const { return that.buffer_ == buffer_; }
void deallocate(pointer p, size_type n) {/*do nothing*/}
size_type max_size() const throw() { return S; }
};
int main()
{
char buffer_[256];
fixed_allocator<char, 256> ator(buffer_);
std::basic_string<char, std::char_traits<char>, fixed_allocator<char, 256> > str(ator);
str.assign("ipsum lorem");
std::cout << "String: '" << str << "' length " << str.size() << std::endl;
std::cout << " has 'l' at " << str.find("l") << std::endl;
str.append(" dolor sit amet");
std::cout << "String: '" << str << "' length " << str.size() << std::endl;
str.insert(0, "I say, ");
std::cout << "String: '" << str << "' length " << str.size() << std::endl;
str.insert(7, "again and again and again, ");
std::cout << "String: '" << str << "' length " << str.size() << std::endl;
str.append(": again and again and again, ");
std::cout << "String: '" << str << "' length " << str.size() << std::endl;
return 0;
}
此代码已在 GCC 和 LLVM 上进行了测试,并按预期(或意外)执行。
语法笨拙。无法从 basic_string 派生并嵌入缓冲区。更好的方法是使用所需的 basic_string 接口子集创建一个小的专用 buffer_string 类。