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
核心代码如下:
//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
相关文章推荐
- 怎么用js实现jq的removeClass方法
- 自己动手写ORM框架(九):实现删除功能Remove方法
- HashMap的原理分析(2)get和remove方法的实现
- 原生js实现addClass,removeClass,hasClass方法
- 用原生js实现addClass,removeClass,hasClass方法
- 原生js实现addClass,removeClass,hasClass方法
- VC6实现激活后台窗口最佳方法
- 关于arm-linux-gcc交叉编译工具链,实现自己的crt0或者编译UBOOT出现undefined reference to `__aeabi_unwind_cpp_pr0'的解决方法
- remove/remove_if算法配合容器的erase方法实现容器删除元素功能
- 真正彻底 实现vc6下 activex dll 的xp风格(theme) 的方法。
- 一个非常有用的关于集合的例子,实现集合的add,remove和this[index]方法
- 【实践】用js 实现 jq 的removeClass 方法
- ArrayList中的remove方法是如何实现的
- 原生js实现addClass,removeClass,hasClass方法
- 当编写一个实体类去实现一个接口,或者抽象类时,在重写的方法上一直提示remove掉@Override;
- 怎么用js实现jq的removeClass方法
- 在vc6实现png图像文件的显示方法
- 原生js实现增加(addclass),删除(removeclass),判断是否存在(hasclass),如果存在删除,如果不存在添加(toggleclass)和获取类名(getbyclass)的方法
- JSONArray 实现兼容老版本API的remove方法
- 怎么用js实现jq的removeClass方法