模板的应用: 判断类型选择合适的传参方式 以提高效率

 一、需求引入

我们都知道,对于一个很大的数据结构而言,采用传值的方式通常是很耗费资源的,因此对于这种数据结构,应该“传const 引用”(或者在C中传递const指针);相反,对于更小的数据结构,情况并非这么简单:通常依赖于实际的代码体系结构,总的来说小的数据结构究竟采取何种传递方式,对性能影响并不大,但是也必须小心处理


二、实现方式

面对   templates,事情变得更为棘手。我们不知道将被用来替换   template parameters 的那个type  到底有多大。此外,最终决定也不仅仅取决于大小:一个伴有「代价高昂之 copy  构造函数」的小  型结构可能会让你醒悟:以  by reference-to-const 传递惟读参数还是比较有道理的。


第一步(第一种方式):根据type的大小选择合适的传参方式

这里我们举个例子:对于不大于2个指针大小的类型,基本模板将采用传值的方式传递参数,而对于其他的类型,将采用传递const引用的方式传递参数

这就让我们联想到了在前一篇博客中提到的IfThenElse模板了

template<typename T> 

class RParam { 

public: 
typedef typename IfThenElse<sizeof(T)<=2*sizeof(void*), 
T, 
T const&>::ResultT
Type; 
};


第二步:即使数据类型很小,也可能涉及昂贵的拷贝构造函数,因此需要编写很多全特化和局部特化

这里以Array<T>的局部特化为例:当参数是Array<T>类型的容器时,采用传递const引用的方式

template<typename T> 
class RParam<Array<T> > { 
public: 
typedef Array<T> const& Type; 
};

...


第三步(第二种方式):上面是对class类型的处理,下面我们希望在基本模板中能对非class类型以传值的方式调用,另外对于某些对性能要求比较苛刻的class类型,我们有选择的添加这些类为“传值”的方式

这让我们联想到了前面一篇博客提到的IsClassT<T> 模板 来鉴定参数是否为class types类型

template<typename T> 

class RParam { 

public: 
typedef  typename  IfThenElse<IsClassT<T>::No, 
T, 
T const&>::ResultT
Type; 
}


第四步:假设我们手里有2个具体类

class MyClass1 { 

public: 
MyClass1 () { 

MyClass1 (MyClass1 const&) { 
std::cout << "MyClass1 copy constructor called\n"; 

}; 
 
class MyClass2 { 

public: 
MyClass2 () { 
}  
MyClass2 (MyClass2 const&) { 
std::cout << "MyClass2 copy constructor called\n"; 

}; 


第五步:针对MyClass2 objects  将以  by value 方式传递 

//全特化

template<> 
class RParam<MyClass2> { 
public: 
typedef MyClass2 Type; 
}; 


第六步:调用上面的模板,采用内联方式可以实现模板实参的推导

//以下函数允许参数以  by value  或  by reference  方式传递 
template <typename T1, typename T2> 
void foo_core (typename RParam<T1>::Type p1, typename RParam<T2>::Type p2) { 
//... 

 
//下面是个  wrapper,用以免除(显式)指定  template parameter的责任 
template <typename T1, typename T2> 
inline 
void foo (T1 const & p1, T2 const & p2) { 
foo_core<T1,T2>(p1,p2); 


三、使用模板

int main() { 
MyClass1 
mc1; 
MyClass2 
mc2; 
foo(mc1,mc2);   //  此式效果相当于  foo_core<MyClass1,MyClass2>(mc1,mc2) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值