Problem with incomplete type while trying to detect existence of a member function
Posted
by abir
on Stack Overflow
See other posts from Stack Overflow
or by abir
Published on 2010-06-17T12:07:57Z
Indexed on
2010/06/17
12:13 UTC
Read the original article
Hit count: 248
I was trying to detect existence of a member function for a class where the function tries to use an incomplete type. The typedef is
struct foo;
typedef std::allocator<foo> foo_alloc;
The detection code is
struct has_alloc
{
template<typename U,U x> struct dummy;
template<typename U>
static char check(dummy<void* (U::*)(std::size_t),&U::allocate>*);
template<typename U>
static char (&check(...))[2];
const static bool value = (sizeof(check<foo_alloc>(0)) == 1);
};
So far I was using incomplete type foo with std::allocator without any error on VS2008.
However when I replaced it with nearly an identical implementation as
template<typename T>
struct allocator
{
T* allocate(std::size_t n)
{
return (T*)operator new (sizeof(T)*n);
}
};
it gives an error saying that as T is incomplete type it has problem instantiating allocator<foo> because allocate uses sizeof.
GCC 4.5 with std::allocator also gives the error, so it seems during detection process the class need to be completely instantiated, even when I am not using that function at all. What I was looking for is void* allocate(std::size_t) which is different from T* allocate(std::size_t).
My questions are (I have three questions, but as they are correlated , so I thought it is better not to create three separate questions).
- Why MS
std::allocatordoesn't check for incomplete typefoowhile instantiating? Are they following any trick which can be implemented ? Why the compiler need to instantiate
allocator<T>to check the existence of the function whensizeofis not used as sfinae mechanism to remove/addallocatein the overload resolutions set? It should be noted that, if I remove the generic implementation of allocate leaving the declaration only, and specialized it for foo afterwards such asstruct foo{}; template<> struct allocator { foo* allocate(std::size_t n) { return (foo*)operator new (sizeof(foo)*n); } };
after
struct has_allocit compiles in GCC 4.5 while gives error in VS2008 asallocator<T>is already instantiated and explicit specialization forallocator<foo>already defined.Is it legal to use nested types for an std::allocator of incomplete type such as
typedef foo_alloc::pointer foo_pointer;? Though it is practically working for me, I suspect the nested types such aspointermay depend on completeness of type it takes. It will be good to know if there is any possible way to typedef such types asfoo_pointerwhere the typepointerdepends on completeness offoo.
NOTE : As the code is not copy paste from editor, it may have some syntax error. Will correct it if I find any. Also the codes (such as allocator) are not complete implementation, I simplified and typed only the portion which I think useful for this particular problem.
© Stack Overflow or respective owner