In C++03, how do I determine if a type T
is dereferenceable?
By which I mean, how do I statically determine if *t
would be a valid expression for t
of type T
?
My attempt:
template<bool B, class T = void> struct enable_if { };
template<class T> struct enable_if<true, T> { typedef T type; };
unsigned char (&helper(void const *))[2];
template<class T>
typename enable_if<
!!sizeof(**static_cast<T *>(NULL)),
unsigned char
>::type helper(T *);
template<class T>
struct is_dereferenceable
{ static bool const value = sizeof(helper(static_cast<T *>(NULL))) == 1; };
struct Test
{
int *operator *();
void operator *() const;
private:
Test(Test const &);
};
int main()
{
std::cout << is_dereferenceable<int *>::value; // should be true
std::cout << is_dereferenceable<void *>::value; // should be false
std::cout << is_dereferenceable<Test>::value; // should be true
std::cout << is_dereferenceable<Test const>::value; // should be false
}
It works on GCC (prints 1010
) but crashes and burns on VC++ (1110
) and Clang (1111
).