您的位置:首页 > 其它

浅谈萃取技术

2016-04-24 21:23 309 查看
在STL中,以泛型技术为中心的设计贯穿着整个设计,模板类的运用,使得代码的复用率大大提高。萃取技术是在模板的基础上,采用相同的方式,却可以将不同的东西提取出来。

为什么要有萃取技术?

模板实现了程序的泛型化,但当有非模板类型传递时,我们就不能只套用模板,还需要对模板的参数进行加设。

template<class T1, class T2>
class MyClass
{
public:
MyClass()
{
cout<<"MyClass<T1, T2>"<<endl;
}
};
template<class T>
class MyClass<T,T>
{
public:
MyClass()
{
cout<<"MyClass<T,T>"<<endl;
}
};
template<class T>
class MyClass<T*,T*>
{
public:
MyClass()
{
cout<<"MyClass<T*,T*>"<<endl;
}
};
int main()
{
MyClass<int,int> mc;
MyClass<int,double> mc1;
MyClass<int*,int*>mc2;
return 0;
}


代码中不同的参数调用不同的模板,编译器根据参数列表进行最优匹配。通过模板参数的推导机制,我们实现了指针所指不同的参数的类型。

但是,我们如果需要不同的返回值时,问题就出现了,同参不同返回值的模板在程序中是不能编译通过的(类似函数的重载,不同返回值的相同函数会导致二义性)。

解决这个问题可以对指向对象类型的制定一个别名。

template <class T>
class A
{
typedef T value_type;
T *ptr;
A(T *p = 0):ptr(p){}
T& operator*()const
{return *ptr;}
};
template <class I>
{
typename I::value_type func(iter)
{return *iter}
};


通过typedef我们返回了ptr和iter两种不同的指针,但这个方法是有很大缺陷的。我们返回的指针都是定义的,但对于原生指针如int *,func是不能接受的。

template partial specialization 偏特化

偏特化的设计思想是加一个中间层,将智能指针和原生指针统统封装起来。

class CIntArray
{
public:
CIntArray()
{
for(int i=0; i<10; ++i)
{
a[i] = i+1;
}
}
int GetSum(int n)
{
int sum = 0;
for(int i=0;i<10; ++i)
{
sum += a[i];
}
return sum ;
}
private:
int a[10];
};

class CFloatArray
{
public:
CFloatArray()
{
for(int i=0; i<10; ++i)
{
f[i] = i+1.11f;
}
}
float GetSum(float n)
{
float sum = 0.0f;
for(int i=0;i<10; ++i)
{
sum += f[i];
}
return sum ;
}
private:
float f[10];
};

template<class T>
class NumTraits
{};

template<>
class NumTraits<CIntArray>
{
public:
typedef int result_type;
typedef int input_type;
};
template<>
class NumTraits<CFloatArray>
{
public:
typedef float result_type;
typedef float input_type;
};

template<class T>
class CApply
{
public:
typename NumTraits<T>::result_type GetSum(T &t,
typename NumTraits<T>::input_type n )
{
cout<<typeid(typename NumTraits<T>::result_type).name()<<endl;
return t.GetSum(n);
}
};


我们将int 型和 float 型分别封装,注意:封装的名字一样哦

这样我们只需调用input_type和result_type.就可以萃取出不同类型int ,float的函数返回值了。

总结下,我们之所以要萃取迭代器相关的类型,无非是要把迭代器相关的类型用于声明局部变量,用作函数的返回值等行为。对于原声指针和其他类型的指针,采用了模板偏特化技术对其的特殊处理,从而达到萃取的目的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: