您的位置:首页 > Web前端

VC6下实现remove_reference的方法。

2008-09-18 22:36 183 查看
VC6对模板的支持很差,有人断言VC6下不可能实现通用的remove_reference。我参考了boost,摘录其中的部分,实现了VC6下可运行的remove_reference。

核心代码如下:


//remove_reference.h


#ifndef _REMOVE_REFERENCE_H_


#define _REMOVE_REFERENCE_H_




namespace boost {




namespace type_traits {




template <class T> struct wrap {};




typedef char yes_type;


struct no_type


{


char padding[8];


};




}// namespace boost::type_traits




namespace detail {




using ::boost::type_traits::yes_type;


using ::boost::type_traits::no_type;


using ::boost::type_traits::wrap;




#define BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(trait,sp,C) \


template<> struct trait##_impl< sp > \


{ \


enum {value = (C)}; \


};




template <class T> T&(* is_reference_helper1(wrap<T>) )(wrap<T>);


char is_reference_helper1(...);




template <class T> no_type is_reference_helper2(T&(*)(wrap<T>));


yes_type is_reference_helper2(...);




template <typename T>


struct is_reference_impl


{


enum{


value = sizeof(


::boost::detail::is_reference_helper2(


::boost::detail::is_reference_helper1(::boost::type_traits::wrap<T>()))) == 1


};


// BOOST_STATIC_CONSTANT(


// bool, value = sizeof(


// ::boost::detail::is_reference_helper2(


// ::boost::detail::is_reference_helper1(::boost::type_traits::wrap<T>()))) == 1


// );


};




BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void,false) // VC6用这一个就可以了,void const等也解决了


// #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS


// BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void const,false)


// BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void volatile,false)


// BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void const volatile,false)


// #endif




} // namespace detail




template <typename T>


struct is_reference


{


enum{


value = detail::is_reference_impl<T>::value


};


};






namespace detail {


template<typename ID>


struct msvc_extract_type


{


struct id2type;


};




template<typename T, typename ID>


struct msvc_register_type : msvc_extract_type<ID>


{


typedef msvc_extract_type<ID> base_type;


struct base_type::id2type // This uses nice VC6.5 and VC7.1 bugfeature


{


typedef T type;


};


};




template<bool IsReference>


struct remove_reference_impl_typeof {


template<typename T,typename ID>


struct inner {


typedef T type;


};


};


template<>


struct remove_reference_impl_typeof<true> {


template<typename T,typename ID>


struct inner {


template<typename U>


static msvc_register_type<U,ID> test(U&(*)());


static msvc_register_type<T,ID> test(...);


//BOOST_STATIC_CONSTANT(unsigned,register_test=sizeof(test( (T(*)())(NULL) ) ));


enum {register_test=sizeof(test( (T(*)())(NULL) ) )};


typedef typename msvc_extract_type<ID>::id2type::type type;


};


};


} //namespace detail




template<typename T>


struct remove_reference {


typedef typename detail::remove_reference_impl_typeof<


boost::is_reference<T>::value


>::template inner<T,remove_reference<T> >::type type;


//BOOST_MPL_AUX_LAMBDA_SUPPORT(1,remove_reference,T)


};




}




#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息