std :: allocator< T>。基本上,在大多数情况下,性能并没有超过基于堆栈的C字符串的形成。但是, * pbufNext; for((pbuf =& aBuffers [buffers - 1], pbufNext = NULL); pbuf> = aBuffers; (pbufNext = pbuf, pbuf - = 1)) pbuf-> bh.pbhNextFree =& pbufNext-> bh; this-> m_buffer_size = buffer_size; this-> m_pbhBufferEnd =& aBuffers [buffers] .bh; this-> m_pbhFirstFree =& aBuffers [0] .bh; } 模板< typename T> 类lallocator:public std :: allocator< T> { public: typedef typename std :: allocator< T> ::指针指针; typedef typename std :: allocator< T> :: size_type size_type; lallocator():m_plbi(m_buffer){assert(m_plbi); } lallocator(lallocator_buffer_if< T> * plbi); lallocator(lallocator const& lc); ~lallocator(){} ; 指针分配(size_type count,void * hint = NULL); void deallocate(指针ptr,size_type计数); lallocator& ; operator =(lallocator const& lc); static void set_buffer(lallocator_buffer_if< T> * b) { m_buffer = b; } public: template< class Other> struct重新绑定 { typedef lallocator< Other>其他; }; 私人: lallocator_buffer_if< T> * m_plbi; 静态__thread lallocator_buffer_if< T> * m_buffer; }; 模板< typename T> __thread lallocator_buffer_if< T> * lallocator< T> :: m_buffer = 0; 模板< typename T> inline lallocator< T> :: lallocator(lallocator_buffer_if< T> * plbi): std :: allocator< T>() { m_plbi = plbi; } 模板< typename T> inline lallocator< T> :: lallocator(lallocator const& lc): std :: allocator< T>(lc) { m_plbi = lc.m_plbi; } 模板< typename T> inline typename lallocator< T> :: pointer lallocator< T> :: allocate(size_type count,void * hint) { T * pt; if(count> m_plbi-> m_buffer_size || (pt = m_p lbi-> pop_buffer())== NULL) 返回std :: allocator< T> :: allocate(count); return pt; } 模板< typename T> inline void lallocator< T> :: deallocate(指针ptr,size_type计数) { if(!m_plbi-> is_yours(ptr)) return (void)std :: allocator< T> :: deallocate(ptr,count); m_plbi-> push_buffer(ptr); } 模板< typename T> inline lallocator< T>& lallocator< T> :: operator =(lallocator< T> const& lc) { 返回m_plbi = lc.m_plbi, *这个; } int main() { typedef std :: basic_string< char,std :: char_traits< char>, lallocator< char> > lallostring; lallocator_buffer< char,5,128> lbc; lallocator< char> lallo(& lbc); lallocator< char> :: set_buffer(& lbc); lallostring lsTest(lallo); lsTest =" sdsdass"; { lallocator_buffer< char,5,128> lbc; lallocator< char> :: set_buffer(& lbc); lallostring lsTest((lallocator< char>(& lbc ))); lsTest + =" abc" + lallostring(" def"); } } 问候,Bane。 [见 http://www.gotw.ca/resources/clcm.htm 有关的信息] [comp.lang.c ++。moderated。第一次海报:做到这一点! ] [comp.std.c ++被审核。要提交文章,请尝试发布] [您的新闻阅读器。如果失败,请使用mailto:st ***** @ ncar.ucar.edu] [---请在发布前查看常见问题解答。 ---] [常见问题: http://www.jamesd.demon.co.uk/csc/faq.html ] This class needs default constructor for rebind purposes.Ok, after correcting compiler errors here is your code:you can make static pointer used for default constructor,into a static thread local storage pointer if needed.There is alwayspossibility that memory allocated withone allocator could be freed with other, so you haveto be carefull not to set different buffers in a scope. #include <string>#include <cassert>//using namespace std;#ifndef __GNUG__#define __thread /* this_would_be_a_great_thing_to_have */#endiftemplate<typename T>class lallocator_buffer_if{protected:template<typename TT, std::size_t buffers, std::size_t buffer_size>friend class lallocator_buffer; template<typename TT>friend class lallocator; private:lallocator_buffer_if() {}T *pop_buffer();void push_buffer( T *pt );bool is_yours( T *pt ); protected:union buffer_header{buffer_header *pbhNextFree;T at[1];}; protected:std::size_t m_buffer_size;buffer_header *m_pbhFirstFree;buffer_header *m_pbhBufferEnd; }; template<typename T>inlineT *lallocator_buffer_if<T>::pop_buffer(){buffer_header *pbh; if( (pbh = m_pbhFirstFree) == NULL )return NULL; return m_pbhFirstFree = pbh->pbhNextFree,&pbh->at[0]; } template<typename T>inlinevoid lallocator_buffer_if<T>::push_buffer( T *pt ){buffer_header *pbh; pbh = (buffer_header *)pt;pbh->pbhNextFree = m_pbhFirstFree;m_pbhFirstFree = pbh; } template<typename T>inlinebool lallocator_buffer_if<T>::is_yours( T *pt ){return (void*)pt >= (void *)this &&pt < &m_pbhBufferEnd->at[0]; } template<typename T, std::size_t buffers, std::size_t buffer_size>class lallocator_buffer : public lallocator_buffer_if<T>{public:lallocator_buffer(); private:union buffer{typename lallocator_buffer_if<T>::buffer_header bh;T atUnReferenced[buffer_size];}; private:buffer aBuffers[buffers]; }; template<typename T, std::size_t buffers, std::size_t buffer_size>inlinelallocator_buffer<T, buffers, buffer_size>::lallocator_buffer(){buffer *pbuf,*pbufNext; for( (pbuf = &aBuffers[buffers - 1],pbufNext = NULL);pbuf >= aBuffers;(pbufNext = pbuf,pbuf -= 1) )pbuf->bh.pbhNextFree = &pbufNext->bh; this->m_buffer_size = buffer_size;this->m_pbhBufferEnd = &aBuffers[buffers].bh;this->m_pbhFirstFree = &aBuffers[0].bh; } template<typename T>class lallocator : public std::allocator<T>{public:typedef typename std::allocator<T>::pointer pointer;typedef typename std::allocator<T>::size_type size_type;lallocator():m_plbi(m_buffer) { assert(m_plbi); }lallocator( lallocator_buffer_if<T> *plbi );lallocator( lallocator const &lc );~lallocator() {};pointer allocate(size_type count, void *hint = NULL );void deallocate( pointer ptr, size_type count );lallocator &operator =( lallocator const &lc ); static void set_buffer(lallocator_buffer_if<T>* b){m_buffer=b;} public:template<class Other>struct rebind{typedef lallocator<Other> other;}; private:lallocator_buffer_if<T> *m_plbi;static __thread lallocator_buffer_if<T>* m_buffer;}; template <typename T>__thread lallocator_buffer_if<T>* lallocator<T>::m_buffer=0; template<typename T>inlinelallocator<T>::lallocator( lallocator_buffer_if<T> *plbi ):std::allocator<T>(){m_plbi = plbi; } template<typename T>inlinelallocator<T>::lallocator( lallocator const &lc ) :std::allocator<T>( lc ){m_plbi = lc.m_plbi; } template<typename T>inlinetypename lallocator<T>::pointer lallocator<T>::allocate( size_typecount, void *hint ){T *pt; if( count > m_plbi->m_buffer_size ||(pt = m_plbi->pop_buffer()) == NULL )return std::allocator<T>::allocate( count ); return pt; } template<typename T>inlinevoid lallocator<T>::deallocate( pointer ptr, size_type count ){if( !m_plbi->is_yours( ptr ) )return (void)std::allocator<T>::deallocate( ptr, count ); m_plbi->push_buffer( ptr ); } template<typename T>inlinelallocator<T>& lallocator<T>::operator =( lallocator<T> const &lc ){return m_plbi = lc.m_plbi,*this; } int main(){typedef std::basic_string<char, std::char_traits<char>,lallocator<char> >lallostring; lallocator_buffer<char, 5, 128> lbc;lallocator<char> lallo( &lbc );lallocator<char>::set_buffer(&lbc);lallostring lsTest( lallo ); lsTest = "sdsdass";{lallocator_buffer<char, 5, 128> lbc;lallocator<char>::set_buffer(&lbc);lallostring lsTest ((lallocator<char>( &lbc)));lsTest+="abc"+lallostring("def");}} Greetings, Bane.[ See http://www.gotw.ca/resources/clcm.htm for info about ][ comp.lang.c++.moderated. First time posters: Do this! ] [ comp.std.c++ is moderated. To submit articles, try just posting with ][ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ][ --- Please see the FAQ before posting. --- ][ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] Oliver S.写道: ... Oliver S. wrote:...不幸的是我的编译器无法吃下面的代码 那不是很具体。如果你指出 ,那么你的编译器说这个代码是难以理解的,这会有很大的帮助。 ...所以这里''我的lalloator(它不是完全符合标准,我使用了一个单一的技巧来防止在lallocator_buffer_if中有一个额外的指针,这会导致我的代码不能用于理论C ++ - 实现;对不起宗教开发者): Unfortunately my compiler isn''t able to eat the following codeThat isn''t very specific. It would help a great deal if you indicatedwhat, precisely, your compiler said was indigestible about this code. ... So here''s my lalloator (it isn''t fully stl-conformant and I used a single trick to prevent having an additional pointer in lallocator_buffer_if which causes my code not to work on theoretical C++-implementations; sorry to all religious developers): 您使用的词语理论和宗教的意味着你认为不合格是不重要的。有可能;但你应该认真考虑你所遇到的问题可能实际上是因为不合格而导致的b $ b。特别是,允许​​实现 假设给定分配器类型的所有实例都相当于(20.1.5p4),这对于你的分配器来说并非如此。虽然 标准鼓励实现者创建实现,但是b 不依赖于这个假设,其中许多实际上确实利用了 该选项,例如,实际上没有复制分配器时 它们具有相同的类型。 std :: list< T,Allocator> :: splice ()特别难以有效地实施 ,除非你假设所有 分配器的实例都是等价的。 [见 http://www.gotw.ca/resources/clcm.htm for info about [comp.lang.c ++。moderated。第一次海报:做到这一点! ] [comp.std.c ++被审核。要提交文章,请尝试发布] [您的新闻阅读器。如果失败,请使用mailto:st ***** @ ncar.ucar.edu] [---请在发布前查看常见问题解答。 ---] [常见问题: http://www.jamesd.demon.co.uk/csc/faq.html ] Your use of the words "theoretical" and "religious" implies that youthink the non-conformance is unimportant. It might be; but you shouldseriously consider the possibility that the problems you''re having mayin fact be due to that non-conformance. In particular, implementationsare allowed to assume that all instances of a given allocator type areequivalent (20.1.5p4), which isn''t the case for your allocators. Whilethe standard encourages implementators to create implementations thatdon''t rely on that assumption, many of them do in fact take advantageof that option, for instance by not actually copying allocators whenthey have the same type. std::list<T,Allocator>::splice() is particularly difficult to implementefficiently unless you build in an assumption that all instances ofAllocator are equivalent.[ See http://www.gotw.ca/resources/clcm.htm for info about ][ comp.lang.c++.moderated. First time posters: Do this! ] [ comp.std.c++ is moderated. To submit articles, try just posting with ][ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ][ --- Please see the FAQ before posting. --- ][ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] 这篇关于我的lallocator&lt; T&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-15 17:52