c – 可以利用std :: basic_string来实现一个长度限制的字符串吗?

前端之家收集整理的这篇文章主要介绍了c – 可以利用std :: basic_string来实现一个长度限制的字符串吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用一个低级API,它接受一个char *和数值来分别表示一个字符串及其长度.我的代码使用std :: basic_string并使用适当的转换调用这些方法.不幸的是,这些方法中的许多接受不同大小的字符串长度(即max(unsigned char),max(short)等等)并且我坚持编写代码以确保我的字符串实例不超过最大长度由低级API规定.

默认情况下,std :: basic_string实例的最大长度由size_t的最大值(max(unsigned int)或max(__ int64))绑定.有没有办法操纵std :: basic_string实现的traits和allocator实现,以便我可以指定自己的类型来代替size_t?通过这样做,我希望利用std :: basic_string实现中的任何现有边界检查,因此在执行转换时我不必这样做.

我的初步调查表明,如果不编写我自己的字符串类,这是不可能的,但我希望我忽略了一些东西:)

解决方法

你可以将自定义分配器传递给std :: basic_string,它具有你想要的最大大小.这应该足够了.也许是这样的:
  1. template <class T>
  2. class my_allocator {
  3. public:
  4. typedef T value_type;
  5.  
  6. typedef std::size_t size_type;
  7. typedef std::ptrdiff_t difference_type;
  8. typedef T* pointer;
  9. typedef const T* const_pointer;
  10. typedef T& reference;
  11. typedef const T& const_reference;
  12.  
  13. pointer address(reference r) const { return &r; }
  14. const_pointer address(const_reference r) const { return &r; }
  15.  
  16. my_allocator() throw() {}
  17.  
  18. template <class U>
  19. my_allocator(const my_allocator<U>&) throw() {}
  20.  
  21. ~my_allocator() throw() {}
  22.  
  23. pointer allocate(size_type n,void * = 0) {
  24. // fail if we try to allocate too much
  25. if((n * sizeof(T))> max_size()) { throw std::bad_alloc(); }
  26. return static_cast<T *>(::operator new(n * sizeof(T)));
  27. }
  28.  
  29. void deallocate(pointer p,size_type) {
  30. return ::operator delete(p);
  31. }
  32.  
  33. void construct(pointer p,const T& val) { new(p) T(val); }
  34. void destroy(pointer p) { p->~T(); }
  35.  
  36. // max out at about 64k
  37. size_type max_size() const throw() { return 0xffff; }
  38.  
  39. template <class U>
  40. struct rebind { typedef my_allocator<U> other; };
  41.  
  42. template <class U>
  43. my_allocator& operator=(const my_allocator<U> &rhs) {
  44. (void)rhs;
  45. return *this;
  46. }
  47. };

然后你可以这样做:

  1. typedef std::basic_string<char,std::char_traits<char>,my_allocator<char> > limited_string;

编辑:我刚刚做了一个测试,以确保它按预期工作.以下代码对其进行测试.

  1. int main() {
  2. limited_string s;
  3. s = "AAAA";
  4. s += s;
  5. s += s;
  6. s += s;
  7. s += s;
  8. s += s;
  9. s += s;
  10. s += s; // 512 chars...
  11. s += s;
  12. s += s;
  13. s += s;
  14. s += s;
  15. s += s;
  16. s += s; // 32768 chars...
  17. s += s; // this will throw std::bad_alloc
  18.  
  19. std::cout << s.max_size() << std::endl;
  20. std::cout << s.size() << std::endl;
  21. }

最后一个s = s将把它放在顶部并导致std :: bad_alloc异常,(因为我的限制只有64k).不幸的是,gcc的std :: basic_string :: max_size()实现不会将其结果基于您使用的分配器,因此它仍然声称能够分配更多. (我不确定这是不是一个错误…).

但这肯定会让你以简单的方式对字符串的大小施加严格的限制.您甚至可以将max size设置为模板参数,这样您只需要为分配器编写一次代码.

猜你在找的C&C++相关文章