|
|||
|
I was often annoyed about the performance of std::basic-string because of complex memory-allocators working in the background to found the work of std::allocator<T>. Basically, the performance doesn't reeach the per- formance of a stack-based C-string in most cases. But nevertheless, the comfort and the implicit protection against buffer-overflows makes std:: basic_string woth to be used. So I searched for a way to have my own stack-based memory-allocation. I came up with the following idea which resulted in a class I called the lallocator (derived from local alloca- tor; this sounds funny in german because to "lall" means to babble in german *g*). First, we have the lallocator-class which is an interface to the locally allocated storage for the stl-object (my lallocator can't be used for strings only). This class is the same for all sizes of local stack-based pools to prevent that we would compile derived stl-classes for any size we use. Second, there's a class called lallocator_buffer_if which is the interface to the local storage we allocated for the lallocator. I defined this interface for all sizes of locally allocated pools to prevent any secial-buffer-size-compiling I mentioned before. Third there's a dervied class of lallocator_buffer_if<T>, called lallocator_buffer<T, buffers, size>; T is the usual data-type in the buffers, buffers is the number of buffers which can be allocated by the lallocator and size is the size of each buffer. Whenever someone tries to do an allocate() on the lallocator and there's a free buffer and the buffer is large enough to satisfy the allocation-request, we'll allocate the buffer from the pool; otherwise we fall back to std::allocator. Here's an example of how this is used: typedef std::basic_string<char, char_traits<char>, lallocator<char> > lallostring; lallocator_buffer<char, 5, 128> lbc; lallocator<char> lallo( &lbc ); lallostring lsTest( lallo ); lsTest = "sdsdass"; Unfortunately my compiler isn't able to eat the following code to prevent explicit instanciation of a lallocator<T>-object: lallocator_buffer<char, 5, 128> lbc; lallostring lsTest( lallocator<char>( &lbc ) ); Does anyone know if there's a conformance-problem here or is this just a bug of my compiler? 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): template<typename T> class lallocator_buffer_if { protected: template<typename T, std::size_t buffers, std::size_t buffer_size> friend class lallocator_buffer; template<typename T> 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> inline T *lallocator_buffer_if<T>: op_buffer(){ buffer_header *pbh; if( (pbh = m_pbhFirstFree) == NULL ) return NULL; return m_pbhFirstFree = pbh->pbhNextFree, &pbh->at[0]; } template<typename T> inline void lallocator_buffer_if<T>: ush_buffer( T *pt ){ buffer_header *pbh; pbh = (buffer_header *)pt; pbh->pbhNextFree = m_pbhFirstFree; m_pbhFirstFree = pbh; } template<typename T> inline bool 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 { buffer_header bh; T atUnReferenced[buffer_size]; }; private: buffer aBuffers[buffers]; }; template<typename T, std::size_t buffers, std::size_t buffer_size> inline lallocator_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; m_buffer_size = buffer_size; m_pbhBufferEnd = &aBuffers[buffers].bh; m_pbhFirstFree = &aBuffers[0].bh; } template<typename T> class lallocator : public std::allocator<T> { public: 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 ); public: template<class Other> struct rebind { typedef lallocator<Other> other; }; private: lallocator_buffer_if<T> *m_plbi; }; template<typename T> inline lallocator<T>::lallocator( lallocator_buffer_if<T> *plbi ) : std::allocator<T>() { m_plbi = plbi; } template<typename T> inline lallocator<T>::lallocator( lallocator const &lc ) : std::allocator<T>( lc ) { m_plbi = lc.m_plbi; } template<typename T> inline typename lallocator<T>: ointer lallocator<T>::allocate( size_type count,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> inline void 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> inline typename lallocator<T> &lallocator<T>: perator =( lallocator const &lc ){ return m_plbi = lc.m_plbi, *this; } [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|
||||
|
||||
|
|
|
|||
|
Oliver S. wrote: > I was often annoyed about the performance of std::basic-string because > of complex memory-allocators working in the background to found the work > of std::allocator<T>. Basically, the performance doesn't reeach the per- > formance of a stack-based C-string in most cases. But nevertheless, the > comfort and the implicit protection against buffer-overflows makes std:: > basic_string woth to be used. So I searched for a way to have my own > stack-based memory-allocation. I came up with the following idea which > resulted in a class I called the lallocator (derived from local alloca- > tor; this sounds funny in german because to "lall" means to babble in > german *g*). > First, we have the lallocator-class which is an interface to the locally > allocated storage for the stl-object (my lallocator can't be used for > strings only). This class is the same for all sizes of local stack-based > pools to prevent that we would compile derived stl-classes for any size > we use. Second, there's a class called lallocator_buffer_if which is the > interface to the local storage we allocated for the lallocator. I defined > this interface for all sizes of locally allocated pools to prevent any > secial-buffer-size-compiling I mentioned before. Third there's a dervied > class of lallocator_buffer_if<T>, called lallocator_buffer<T, buffers, > size>; T is the usual data-type in the buffers, buffers is the number of > buffers which can be allocated by the lallocator and size is the size of > each buffer. Whenever someone tries to do an allocate() on the lallocator > and there's a free buffer and the buffer is large enough to satisfy the > allocation-request, we'll allocate the buffer from the pool; otherwise > we fall back to std::allocator. > > Here's an example of how this is used: > > typedef std::basic_string<char, char_traits<char>, lallocator<char> > > lallostring; > > lallocator_buffer<char, 5, 128> lbc; > lallocator<char> lallo( &lbc ); > lallostring lsTest( lallo ); > > lsTest = "sdsdass"; > > Unfortunately my compiler isn't able to eat the following code > to prevent explicit instanciation of a lallocator<T>-object: > > lallocator_buffer<char, 5, 128> lbc; > lallostring lsTest( lallocator<char>( &lbc ) ); > > Does anyone know if there's a conformance-problem here or is this > just a bug of my compiler? > > > 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): >... Actually, there is nothing wrong with the union of the buffer and the pointer to the next free buffer. It follows the standard design for a memory pool - which is what you have implemented. See boost's "pool" library for another example of a memory pool. Memory pools work best for constant sized memory allocations - while std::string allocations will vary in size. But since std::string often makes many small allocations, there can still be some benefit from using a sufficiently large size for the memory pool blocks. An even more effective optimization would to add a fixed-sized character buffer data member to the string class itself. By so doing, the performance for std::strings would equal that of stack-based strings for strings shorter than a certain length. Greg [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
Oliver S. wrote: > I was often annoyed about the performance of std::basic-string because > of complex memory-allocators working in the background to found the work > of std::allocator<T>. Basically, the performance doesn't reeach the per- > formance of a stack-based C-string in most cases. But nevertheless, the > comfort and the implicit protection against buffer-overflows makes std:: > basic_string woth to be used. So I searched for a way to have my own > stack-based memory-allocation. I came up with the following idea which > resulted in a class I called the lallocator (derived from local alloca- > tor; this sounds funny in german because to "lall" means to babble in > german *g*). > > Here's an example of how this is used: > > typedef std::basic_string<char, char_traits<char>, lallocator<char> > > lallostring; > > lallocator_buffer<char, 5, 128> lbc; > lallocator<char> lallo( &lbc ); > lallostring lsTest( lallo ); > > lsTest = "sdsdass"; > > Unfortunately my compiler isn't able to eat the following code > to prevent explicit instanciation of a lallocator<T>-object: > > lallocator_buffer<char, 5, 128> lbc; > lallostring lsTest( lallocator<char>( &lbc ) ); Oh, this is just common error you have declared function. > > template<typename T> > class lallocator : public std::allocator<T> > { > public: > 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 ); > > public: > template<class Other> > struct rebind > { > typedef lallocator<Other> other; > }; > > private: > lallocator_buffer_if<T> *m_plbi; > }; > 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 with one allocator could be freed with other, so you have to 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 */ #endif template<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> inline T *lallocator_buffer_if<T>: op_buffer(){ buffer_header *pbh; if( (pbh = m_pbhFirstFree) == NULL ) return NULL; return m_pbhFirstFree = pbh->pbhNextFree, &pbh->at[0]; } template<typename T> inline void lallocator_buffer_if<T>: ush_buffer( T *pt ){ buffer_header *pbh; pbh = (buffer_header *)pt; pbh->pbhNextFree = m_pbhFirstFree; m_pbhFirstFree = pbh; } template<typename T> inline bool 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> inline lallocator_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>: ointer 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> inline lallocator<T>::lallocator( lallocator_buffer_if<T> *plbi ): std::allocator<T>() { m_plbi = plbi; } template<typename T> inline lallocator<T>::lallocator( lallocator const &lc ) : std::allocator<T>( lc ) { m_plbi = lc.m_plbi; } template<typename T> inline typename lallocator<T>: ointer 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> inline void 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> inline lallocator<T>& lallocator<T>: perator =( 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
Oliver S. wrote: ... > Unfortunately my compiler isn't able to eat the following code That isn't very specific. It would help a great deal if you indicated what, 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): Your use of the words "theoretical" and "religious" implies that you think the non-conformance is unimportant. It might be; but you should seriously consider the possibility that the problems you're having may in fact be due to that non-conformance. In particular, implementations are allowed to assume that all instances of a given allocator type are equivalent (20.1.5p4), which isn't the case for your allocators. While the standard encourages implementators to create implementations that don't rely on that assumption, many of them do in fact take advantage of that option, for instance by not actually copying allocators when they have the same type. std::list<T,Allocator>::splice() is particularly difficult to implement efficiently unless you build in an assumption that all instances of Allocator 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
Oliver S. wrote: [] >> Unfortunately my compiler isn't able to eat the following code >> to prevent explicit instanciation of a lallocator<T>-object: >> >> lallocator_buffer<char, 5, 128> lbc; >> lallostring lsTest( lallocator<char>( &lbc ) ); >> >> Does anyone know if there's a conformance-problem here or is this >> just a bug of my compiler? You could try putting additional parenthesis like this: lallostring lsTest( ( lallocator<char>( &lbc ) ) ); [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
Oliver S. wrote: >> Does anyone know if there's a conformance-problem here or is this > just a bug of my compiler? In this paper on Using Stateful Allocator with the STL there is some code that I've used on a number of platforms, with all the major STL versions http://www.lancediduck.com/papers/Cpp/StatefulSTL.pdf [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
> Actually, there is nothing wrong with the union of the buffer and the > pointer to the next free buffer. ... That's not the in-conformance I thought about. Look at is_yours in the base-class and you can find this in-conformance which might offense some religious C++ers. > Memory pools work best for constant sized memory allocations ... Mine does work equally good for everything up to the limit for a buffer. > An even more effective optimization would to add a fixed-sized character > buffer data member to the string class itself. Maybe, but this wouldn't be a genral-purpose-string anymore because every string would carry around a buffer that might not be used. [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
> In this paper on Using Stateful Allocator with the STL there is some > code that I've used on a number of platforms, with all the major STL > versions ... Nearly the same idea, but very low-levelish in your flavour. I think mine is a bit more comfortable. [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
> While the standard encourages implementators to create implementations > that don't rely on that assumption, many of them do in fact take advantage > of that option, for instance by not actually copying allocators when > they have the same type. I intentionally missed a default-constructor to prevent that and thereby enforce a compilation-error. [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
> You could try putting additional parenthesis like this: > > lallostring lsTest( ( lallocator<char>( &lbc ) ) ); Thanks, but that doesn't help! [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
Oliver S. wrote: > > Actually, there is nothing wrong with the union of the buffer and the > > pointer to the next free buffer. ... > > That's not the in-conformance I thought about. Look at is_yours in the > base-class and you can find this in-conformance which might offense some > religious C++ers. I'm not sure I follow that; in what sense is it non-conformant? I'm sure it will be obvious two minutes after I post this message, but right now it isn't. [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
Oliver S. wrote: > > Actually, there is nothing wrong with the union of the buffer and the > > pointer to the next free buffer. ... > > That's not the in-conformance I thought about. Look at is_yours in the > base-class and you can find this in-conformance which might offense some > religious C++ers. I'm not sure why is_yours() compares the pointer against the pointer to the buffer. Comparing it against the first item in the buffer's array would certainly be a valid test: template<typename T> inline bool lallocator_buffer_if<T>::is_yours( T *pt ) { return pt >= &at[0] and pt < &m_pbhBufferEnd->at[0]; } > > Memory pools work best for constant sized memory allocations ... > > Mine does work equally good for everything up to the limit for a buffer. Using fixed sized memory blocks to speed up variably-sized allocations has two principal shortcomings: oversized allocations see no benefit, while undersized allocations waste memory. > > An even more effective optimization would to add a fixed-sized character > > buffer data member to the string class itself. > > Maybe, but this wouldn't be a genral-purpose-string anymore because > every string would carry around a buffer that might not be used. The string with an internal character buffer would still be general purpose - oversized strings would continue to allocate their character buffer dynamically. An unused internal character buffer wastes no more memory than the memory wasted by deallocated a fixed-sized buffer. After all, deallocated buffers are never really "freed" (that is, returned to the general memory pool where it can be used to fulfill any subsequent memory allocation request). Rather freed buffers are held in reserve just in case a future string allocation could use it. A string with an internal buffer on the other hand, returns the buffer to the general purpose memory pool (or the stack) upon its destruction. A further advantage that an internal character buffer has over external storage is that it adds no meaningful delay when constructing or copying a string object. The entire internal character buffer does not need to be initialized or copied with the string, just the portion that contains the string's characters. Greg [ 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:std-c++@ncar.ucar.edu ] [ --- Please see the FAQ before posting. --- ] [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ] |
|
|||
|
>> lallocator_buffer<char, 5, 128> lbc;
>> lallostring lsTest( lallocator<char>( &lbc ) ); > Oh, this is just common error you have declared function. Ok, these seem to have priority over variable-definitions. > This class needs default constructor for rebind purposes. I won't supply a default-constructor because I want the STL-classes used with my lallocator<T> to work with the pools attached to the allocator-objects. The allocator-objects usually stored internally in the STL-container-classes are typically rebind'ed versions of the supplied allocator-type to allow for the allocators supplied to the constructor of the stl-container to be of a dif- ferent type. These allocator-objects are created through a copy-constructor I supply. As the major STL-implementations are prepared for stateful alloca- tors as far as possible, this works. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|