|
Boost : |
From: Robert Ramey (ramey_at_[hidden])
Date: 2003-12-05 16:43:56
David Abrahams wrote:
http://lists.boost.org/MailArchives/boost/msg53875.php
in response the above I crafted the following functions to allocate space
for a type from the heap without invoking a constructor. The intention
is to use the correct new - either a specific class overload one if
it exists or a the global one if it doesn't.
I get errors on the two compilers I used. GCC 3.2 under cygwin
just crashes with:
c:/boost-dev/libs/serialization/test/test_zmisc.cpp: In instantiation of `heap_allocator<A>':
c:/boost-dev/libs/serialization/test/test_zmisc.cpp:48: instantiated from here
c:/boost-dev/libs/serialization/test/test_zmisc.cpp:21: internal error:
Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.
while VC 7.0 gives me:
c:\boost-dev\libs\serialization\test\test_zmisc.cpp(21) : error C2275: 'new' : illegal use of this type as an expression
c:\boost-dev\libs\serialization\test\test_zmisc.cpp(48) : see reference to class template instantiation 'heap_allocator<T>' being compiled
with
[
T=A
]
c:\boost-dev\libs\serialization\test\test_zmisc.cpp(21) : error C2955: 'heap_allocator<T>::test' : use of class template requires template argument list
with
[
T=A
]
c:\boost-dev\libs\serialization\test\test_zmisc.cpp(17) : see declaration of 'heap_allocator<T>::test'
with
[
T=A
]
...
Could you help me out with this?
Robert Ramey
#include <new>
// note trick to be sure that operator new is using class specific
// version if such exists. Due to Peter Dimov.
// note: the following fails if T has no default constructor.
// otherwise it would have been ideal
//struct heap_allocator : public T
//{
// T * invoke(){
// return ::new(sizeof(T));
// }
//}
template<class T>
struct heap_allocator
{
template <class U, U x> struct test;
typedef char* yes;
typedef int* no;
template <class U>
yes has_op_new(U*, test<void* (*)(std::size_t), & U::operator new> * = 0);
no has_op_new(...);
template<class U>
T * new_operator(U);
T * new_operator(yes){
return (T::operator new)(sizeof(T));
}
T * new_operator(no){
return static_cast<T *>(operator new(sizeof(T)));
}
static T * invoke(){
return new_operator(has_op_new(static_cast<T *>(NULL)));
}
};
class A {
};
class B {
public:
void * operator new(size_t s);
};
int
main(int argc, char *argv[]){
A * a = heap_allocator<A>::invoke(); // never throws ?
B * b = heap_allocator<B>::invoke(); // never throws ?
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk