VC6下实现remove_reference的方法。

简介:
6对模板的支持很差,有人断言VC6下不可能实现通用的remove_reference。我参考了boost,摘录其中的部分,实现了VC6下可运行的remove_reference。
 
核心代码如下:
 
InBlock.gif //remove_reference.h 
InBlock.gif#ifndef _REMOVE_REFERENCE_H_ 
InBlock.gif#define _REMOVE_REFERENCE_H_ 
InBlock.gif 
InBlock.gif namespace boost { 
InBlock.gif 
InBlock.gif namespace type_traits { 
InBlock.gif     
InBlock.gif    template < class T>  struct wrap {}; 
InBlock.gif 
InBlock.gif    typedef  char yes_type; 
InBlock.gif     struct no_type 
InBlock.gif    { 
InBlock.gif       char padding[8]; 
InBlock.gif    }; 
InBlock.gif     
InBlock.gif} // namespace boost::type_traits 
InBlock.gif 
InBlock.gif namespace detail { 
InBlock.gif    
InBlock.gif   using ::boost::type_traits::yes_type; 
InBlock.gif   using ::boost::type_traits::no_type; 
InBlock.gif   using ::boost::type_traits::wrap; 
InBlock.gif 
InBlock.gif#define BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(trait,sp,C) \ 
InBlock.gif  template<>  struct trait##_impl< sp > \ 
InBlock.gif  { \ 
InBlock.gif   enum {value = (C)}; \ 
InBlock.gif  };    
InBlock.gif    
InBlock.gif  template < class T> T&(* is_reference_helper1(wrap<T>) )(wrap<T>); 
InBlock.gif   char is_reference_helper1(...); 
InBlock.gif    
InBlock.gif  template < class T> no_type is_reference_helper2(T&(*)(wrap<T>)); 
InBlock.gif  yes_type is_reference_helper2(...); 
InBlock.gif    
InBlock.gif  template <typename T> 
InBlock.gif     struct is_reference_impl 
InBlock.gif  { 
InBlock.gif     enum
InBlock.gif      value =  sizeof
InBlock.gif        ::boost::detail::is_reference_helper2( 
InBlock.gif        ::boost::detail::is_reference_helper1(::boost::type_traits::wrap<T>()))) == 1 
InBlock.gif    }; 
InBlock.gif     //      BOOST_STATIC_CONSTANT( 
InBlock.gif     //        bool, value = sizeof( 
InBlock.gif     //                         ::boost::detail::is_reference_helper2( 
InBlock.gif     //        ::boost::detail::is_reference_helper1(::boost::type_traits::wrap<T>()))) == 1 
InBlock.gif     //        ); 
InBlock.gif  }; 
InBlock.gif 
InBlock.gif    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference, void, false// VC6用这一个就可以了,void const等也解决了 
InBlock.gif //    #ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS 
InBlock.gif //    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void const,false) 
InBlock.gif //    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void volatile,false) 
InBlock.gif //    BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_reference,void const volatile,false) 
InBlock.gif //    #endif 
InBlock.gif     
InBlock.gif// namespace detail 
InBlock.gif 
InBlock.giftemplate <typename T> 
InBlock.gif struct is_reference 
InBlock.gif
InBlock.gif   enum
InBlock.gif    value = detail::is_reference_impl<T>::value 
InBlock.gif  }; 
InBlock.gif}; 
InBlock.gif 
InBlock.gif 
InBlock.gif namespace detail { 
InBlock.gif  template<typename ID> 
InBlock.gif                 struct msvc_extract_type 
InBlock.gif  { 
InBlock.gif     struct id2type; 
InBlock.gif  }; 
InBlock.gif    
InBlock.gif  template<typename T, typename ID> 
InBlock.gif                 struct msvc_register_type : msvc_extract_type<ID> 
InBlock.gif  { 
InBlock.gif    typedef msvc_extract_type<ID> base_type; 
InBlock.gif     struct base_type::id2type  // This uses nice VC6.5 and VC7.1 bugfeature 
InBlock.gif    { 
InBlock.gif      typedef T type; 
InBlock.gif    }; 
InBlock.gif        }; 
InBlock.gif    
InBlock.gif  template< bool IsReference> 
InBlock.gif                 struct remove_reference_impl_typeof { 
InBlock.gif    template<typename T,typename ID> 
InBlock.gif                         struct inner { 
InBlock.gif      typedef T type; 
InBlock.gif    }; 
InBlock.gif  }; 
InBlock.gif  template<> 
InBlock.gif                 struct remove_reference_impl_typeof< true> { 
InBlock.gif    template<typename T,typename ID> 
InBlock.gif                         struct inner { 
InBlock.gif      template<typename U> 
InBlock.gif                                 static msvc_register_type<U,ID> test(U&(*)()); 
InBlock.gif       static msvc_register_type<T,ID> test(...); 
InBlock.gif       //BOOST_STATIC_CONSTANT(unsigned,register_test=sizeof(test( (T(*)())(NULL) ) )); 
InBlock.gif       enum {register_test= sizeof(test( (T(*)())(NULL) ) )}; 
InBlock.gif      typedef typename msvc_extract_type<ID>::id2type::type type; 
InBlock.gif    }; 
InBlock.gif  }; 
InBlock.gif//namespace detail 
InBlock.gif 
InBlock.giftemplate<typename T> 
InBlock.gif struct remove_reference { 
InBlock.gif  typedef typename detail::remove_reference_impl_typeof< 
InBlock.gif    boost::is_reference<T>::value 
InBlock.gif                >::template inner<T,remove_reference<T> >::type type; 
InBlock.gif   //BOOST_MPL_AUX_LAMBDA_SUPPORT(1,remove_reference,T) 
InBlock.gif        }; 
InBlock.gif 
InBlock.gif}    
InBlock.gif 
InBlock.gif#endif
















本文转sinojelly51CTO博客,原文链接:http://blog.51cto.com/sinojelly/100307 ,如需转载请自行联系原作者
相关文章
|
9月前
|
存储 SQL API
VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
VB中判断空的几种方法,Null, Missing, Empty, Nothing, vbNullString区别
|
10月前
|
Ubuntu C语言
【ubuntu】2.c:(.text+0xd2): undefined reference to `pthread_create‘ collect2: error: ld returned
【ubuntu】2.c:(.text+0xd2): undefined reference to `pthread_create‘ collect2: error: ld returned
102 0
关于 CMake编译出出现错误“Could not find compiler set in environment variable RC:” 的解决方法
关于 CMake编译出出现错误“Could not find compiler set in environment variable RC:” 的解决方法
关于 CMake编译出出现错误“Could not find compiler set in environment variable RC:” 的解决方法
对‘avformat_find_stream_info’未定义的引用、to the PKG_CONFIG_PATH environment variable
对‘avformat_find_stream_info’未定义的引用、to the PKG_CONFIG_PATH environment variable
64 0
undefined reference to `swr_init+
undefined reference to `swr_init+
90 0
CodeBlocks中运行出现undifined reference to std::cxxll:basic_string错误解决方案
CodeBlocks中运行出现undifined reference to std::cxxll:basic_string错误解决方案
183 0
CodeBlocks中运行出现undifined reference to std::cxxll:basic_string错误解决方案
|
Linux
解决办法:error: <item> inner element must either be a resource reference or empty.
解决办法:error: <item> inner element must either be a resource reference or empty.
210 0
|
Java 编译器
IDEA 编译器在变量上面报 Content of collection are updated, but never queried
IDEA 编译器在变量上面报 Content of collection are updated, but never queried
885 0
IDEA 编译器在变量上面报 Content of collection are updated, but never queried
SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
SAP QM 执行事务代码QP01,系统报错 -Material type FOOD is not defined for task list type Q-
|
程序员 编译器 C语言
解决办法:undefined reference to symbol '_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3
解决办法:undefined reference to symbol '_ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3
762 0