//#ifndef _TRAIT_H_
//#define _TRAIT_H_
#include <iostream>
using namespace std;
#if 0
//模板参数推导机制只能推导参数的类型,而不能推导返回值的类型,该如何做呢?
方法1:可以声明内嵌型别;(对一般的类可以对其定义内嵌型别,但对原生指针(最朴
素的指针:int * ,char * 一般的类等),则无法将其定义为内嵌型别?
(如int * p = new int[10]));??
方法2:可以用萃取技术:
小知识点:指针分为:泛型指针,原生指针,智能指针
(1)泛型指针:如void * ,可以指向任何的数据类型,因此具有泛型的含义。
(2)原生指针:最朴素的指针,如int*char* 一般的类等,但是如果重载了*->运算符
的类就不是原生指针,也就是拐着弯,变着法,指向对象的指针。
(3)智能指针:智能指针是C++里面的内容,c++语言没有自动的内存回收机制,程序员得每次自己处理内存问题,采用智能指针可以缓解这类问题。采用智能指针主要是为了防止悬垂指针(指向曾经存在的对象,但该对象已经不复存在)的情况:一般是把指针封装到一个智能指针类中,这个类中还封装了一个使用计数器,对指针的赋值等操作将导致计数器值+1,对指针的delete 操作将导致其-1,值为0时,指针为NULL。
方法3:偏特化设计:偏特化是指提供另一份模板定义:也就是说,针对模板参数更进一步的条件限制所设计出来的特化版本。
*******************************************************************************
(*****)对于模板,模板的特化,模板的偏特化,都存在的情况,编译器在编译阶段进行匹配时,我的理解是:从哲学的角度看,先照顾最特殊的,然后才是次特殊,最后才是普通的。
*******************************************************************************
#endif
#if 0
//方法1:内嵌
template<typename I>
struct Test
{
typedef I value_type;
public:
Test(I* a): x(a){}
~Test()
{
delete(x);
}
public:
I& operator*()
{
return *x;
}
public:
I*x;
};
template <typename T>
typename T::value_type Fun(T test) //返回值typename不能省,因为要说明value是一个类型,不然编译器
//在没有没有将类型具体化之前,其无法识别typename 是类型型别还是函数成员..
{
return *test;
}
int main()
{
Test<int> test(new int(10));
cout << Fun(test) << endl;
return 0;
}
#endif
*******************************************************************************
//方法2 :萃取(模板的特化)
#if 0
template <typename T>
struct my_itreator_traits //首先定义这个“特性萃取机”结构体,把程序中需要用到的所有的性别装进去
{
typedef typename T::value_type value_type;
typedef typename T::point point;
typedef typename T::reference reference;
};
template<typename T>
class Test
{
public: //必须要在自己定义的新类中声明对应的类型
typedef T value_type;
typedef T* point;
typedef T& reference;
public:
//T* ptr;
Test(T* q = 0):ptr(q){}
T& operator*()
{
return *ptr;
}
T* operator&()
{
return ptr;
}
public:
value_type MyFun(T i); //为何可以在类中声明,也可以不用在类中声明??
private:
T* ptr;
};
template<typename T>
typenamemy_itreator_traits<T>::value_type
MyFun(T i)
{
return *i;
}
int main(void)
{
int a = 8;
Test<int> test(new int(10));
cout << MyFun(test) << endl;
return 0;
}
//#endif
#endif
*******************************************************************************
//方法3:偏特化设计
//-----------------------------------------------------------------------------------------------------------template<typenameT>
struct my_itreator_traits
{
typename T::value_type value_type;
typename T::difference_type difference_type;
typename T::iterator_category iterator_category;
typename T::pointer pointer;
typename T::reference reference;
};
//specialize for T*
template<typename Tp> //偏特化(T*)--迭代器是一个原生指针
struct my_itreator_traits<Tp *>
{
typedef random_access_iterator_tag iterator_category;
typedef Tp value_type;
typedef Tp* pointer;
typedef Tp& reference;
typedef ptrdiff_t difference_type;
};
//specialize for const T*
template<typename Tp> //偏特化(const T*)--迭代器是一个原生指针指向常量
struct my_itreator_traits<const Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef Tp value_type;
typedef const Tp* pointer;
typedef const Tp& reference;
typedef ptrdiff_t difference_type;
};
//以上两者萃取出来的型别都是T 而非const T
//-----------------------------------------------------------------------------------------------------------
//一般化设计
template<typename T,typename T1>
class TestClass
{
public:
TestClass() //只设计构造就ok
{
cout<<"T* T1*" << endl;
}
};
//针对普通指针的偏特化设计
template<typename T,typename T1>
class TestClass<T*, T1*>
{
public:
TestClass() //只设计构造就ok
{
cout<<"T* T1*" << endl;
}
};
//针对const 指针的偏特化设计
template<typename T,class T1>
class TestClass<const T*, T1*>
{
public:
TestClass() //只设计构造就ok
{
cout<<"T* T1*" << endl;
}
};
int main(void)
{
TestClass<int,char> obj;
TestClass<int*,char*> obj1;//对于原生指针作为类型参数,采用偏特化萃取方法
TestClass<const int*,char> obj2;//对于指向常量的指针. 同样采用偏特化萃取方法
return 0;
}