新版C++实现auto关键字, 其实可以在C++98基本的
template、sizeof及函数类型重载结合的类型推导方法实现自己恶心的auto,下面的代码取自boost typeof的实现()。在vs2005编译环境调试。
-
#include <typeinfo>
-
#include <iostream>
-
using namespace std;
-
-
struct msvc_extract_type_default_param {};
-
-
template<typename ID, typename T = msvc_extract_type_default_param>
-
struct msvc_extract_type;
-
-
template<typename ID>
-
struct msvc_extract_type<ID, msvc_extract_type_default_param>
-
{
-
template<bool>
-
struct id2type_impl;
-
-
typedef id2type_impl<true> id2type;
-
};
-
-
template<typename ID, typename T>
-
struct msvc_extract_type : msvc_extract_type<ID, msvc_extract_type_default_param>
-
{
-
template<>
-
struct id2type_impl<true> //VC8.0 specific bugfeature
-
{
-
typedef T type;
-
};
-
-
template<bool>
-
struct id2type_impl;
-
-
typedef id2type_impl<true> id2type;
-
};
-
-
template<typename T, typename ID>
-
struct msvc_register_type : msvc_extract_type<ID, T>
-
{
-
};
-
-
#define BOOST_MPL_AUX_NTTP_DECL(T, x) T x
-
-
template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
-
struct int_;
-
-
template<int ID>
-
struct msvc_typeid_wrapper
-
{
-
typedef typename msvc_extract_type<int_<ID> >::id2type id2type;
-
typedef typename id2type::type type;
-
};
-
-
//Workaround for ETI-bug for VC6 and VC7
-
template<>
-
struct msvc_typeid_wrapper<1>
-
{
-
typedef msvc_typeid_wrapper<1> type;
-
};
-
-
//Workaround for ETI-bug for VC7.1
-
template<>
-
struct msvc_typeid_wrapper<4>
-
{
-
typedef msvc_typeid_wrapper<4> type;
-
};
-
-
//Tie it all together
-
template<typename T>
-
struct encode_type
-
{
-
enum:long {value = 2};// by compile time, modify value to implement type system support multi SELF_TYPEOF using;
-
typedef typename msvc_register_type<T, int_<value> >::id2type type;
-
};
-
-
template<class T>
-
struct sizer
-
{
-
typedef char(*type)[encode_type<T>::value];
-
};
-
-
template<typename T>
-
typename sizer<T>::type encode_start(T const&);
-
-
template<typename T>
-
typename sizer<T>::type encode_start(T&);
-
-
#define SELF_TYPEOF(expr) \
-
msvc_typeid_wrapper<sizeof(*encode_start(expr)) >::type
-
-
int main(int argc, char* argv[])
-
{
-
std::string str("this is first str");
-
SELF_TYPEOF(str) strAnother("this is another");
-
cout<<"the type of strAnother is = "<<typeid(strAnother).name()<<"\tstrAnother value = "<<strAnother.c_str()<<endl;
-
-
SELF_TYPEOF(str) strThird("this is Third");
-
cout<<"the type of strThird is= "<<typeid(strThird).name()<<"\tstrThird value = "<<strThird.c_str()<<endl;
-
-
return 0;
-
}
输出结果为:
-
the type of strAnother is = class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > strAnother value = this is another
-
the type of strThird is = class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > strThird value = this strThird Third
(一)实现中使用
-
template<>
-
struct id2type_impl<true> //VC8.0 specific bugfeature
-
{
-
typedef T type;
-
};
中的type来
存储类型推导得到的类型。
(二)使用代码
-
template<typename T>
-
typename sizer<T>::type encode_start(T&);
推导需要的类型。
(三)在代码中注册需要的类型
-
//Tie it all together
-
template<typename T>
-
struct encode_type
-
{
-
enum:long {value = 2};// by compile time, modify value to implement type system support multi SELF_TYPEOF using;
-
typedef typename msvc_register_type<T, int_<value> >::id2type type;
-
};
其中encode_type中的enum成员value是用来注册的ID。
其中,要实现多类型注册,需要在编译时动态索引和改变value值。
(四)使用代码如下代码
从前面注册的类型存储中,得到需要的类型。
-
template<class T>
-
struct sizer
-
{
-
typedef char(*type)[encode_type<T>::value];
-
};
-
-
-
#define SELF_TYPEOF(expr) \
-
msvc_typeid_wrapper<sizeof(*encode_start(expr)) >::type
其中,为得到存储类型,代码
-
template<class T>
-
struct sizer
-
{
-
typedef char(*type)[encode_type<T>::value];
-
};
充当了
索引的功能,使用sizeof来得到存储类型的ID。
所以实现的编译推导顺序是:(二)-> (三)->(一)-> (四),即先推导在注册类型,并使用结构体存储类型,然后根据相应索引在存储结构体中索引得到类型。以上的推导中需编译期改变enum:long {value = 2}中的value值来改进类型推导。
阅读(2264) | 评论(0) | 转发(0) |