在C 03中,如何确定类型T是否可解除引用?
我的意思是,我如何静态地确定* t是否是T类型t的有效表达式?
我的意思是,我如何静态地确定* t是否是T类型t的有效表达式?
我的尝试:
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 }
它适用于GCC(打印1010),但在VC(1110)和Clang(1111)上崩溃和灼伤.
解决方法
#include <boost\type_traits\remove_cv.hpp> #include <boost\type_traits\is_same.hpp> #include <boost\type_traits\remove_pointer.hpp> #include <boost\type_traits\is_arithmetic.hpp> #include <boost\utility\enable_if.hpp> namespace detail { struct tag { template < typename _T > tag(const _T &); }; // This operator will be used if there is no 'real' operator tag operator*(const tag &); // This is need in case of operator * return type is void tag operator,(tag,int); unsigned char (&helper(tag))[2]; template < typename _T > unsigned char helper(const _T &); template < typename _T,typename _Enable = void > struct traits { static const bool value = (sizeof(helper(((**static_cast <_T*>(NULL)),0))) == 1); }; // specialization for void pointers template < typename _T > struct traits < _T,typename boost::enable_if < typename boost::is_same < typename boost::remove_cv < typename boost::remove_pointer < _T > ::type > ::type,void > > ::type > { static const bool value = false; }; // specialization for arithmetic types template < typename _T > struct traits < _T,typename boost::enable_if < typename boost::is_arithmetic < typename boost::remove_cv < _T > ::type > > ::type > { static const bool value = false; }; } template < typename _T > struct is_dereferenceable : public detail::traits < _T > { };
我在msvs 2008中测试过它