模板的细节改进

模板的别名
传统方法使用关键字typedef定义类型的别名,他有一些限制,比如无法定义模板类型的别名
考虑这样一个场景:
typedef std::map<std::string, int> map_int_t;
//........
typedef std::map<std::string, std::string> map_str_t;
//........

我们需要一个固定以std::string为key的map,他可以映射到int或是另一个std::string,但为了定义这样一个模板的别名,我们不得不加一个外敷类:
template <typename Val>  
struct str_map  
{  
     typed std::map<std::string, Val> type;  
};  
 //.... 
  
str_map<int>::type ma; 
//...

加外敷类str_map让人感到繁琐......


使用C++11中出现的别名声明,我们可以直接给模板定义别名:
template <typename Val>  
using str_map = std::map<std::string, Val>;  
//...
  
str_map<int> map1;  


注:使用方法: using A = B; //A是B的同义词,是B的别名 using的使用方式类似赋值,将赋值号右边的类型赋给左边的类型
使用using的效果与使用typedef的效果一致,只是语法不同
使用using定义的别名,只要是类型名能出现的地方,别名都能出现


再来一个例子对比一下:
template <typename T>  
struct fun_t  
{  
     typedef void (*type)(T, T);  
};  
  
fun_t<int>::type xx_1;  
  
template <typename T>  
using func_t = void(*)(T, T);  
  
func_t<int> xx_2;  


使用using定义模板时,只是在普通类型别名语句的基础上加上template参数列表即可,而不需要像typedef使用外敷模板。


函数模板的默认参数
在C++98/03中,类模板可以有默认模板参数,而函数模板不支持默认模板参数。
template <typename T, typename U =int, U N = 0>  
struct Foo  
{  
     //...  
};  
  
  
template <typename T = int>  	//error
void func()  
{  
     //...  
} 




在C++11中上面的func函数是可以直接使用,

在函数模板的调用中,如果所有模板参数都有默认参数时,就可以像普通函数一样进行调用。
而在类模板中,哪怕所有模板参数都有默认参数,在使用时也必须在模板名后跟随"<>"来实例化
int main()
{
	Foo<> foo;
	func();
	return 0;
}

函数模板的默认模板参数不像普通函数的默认参数一样必须从右往左提供函数模板的默认模板参数。函数模板的默认模板参数也可以和自动推导结合起来使用:
template <typename R = int, typename U>  
R func(U val)  
{  
	val;  
}  
  
int main()
{  
     func(123);  	//返回值默认为int	U自动推导为int		且默认模板参数并未从右向左提供
     return 0;  
}  


需要注意的一点,显示调用函数模板时,即调用时显示指定模板参数时,参数填充顺序是从左向右的:
func<long>(123); //返回值类型为long而不是默认的int


当同时使用函数模的默认模板参数与自动推导时,会板优先自动推导,如果能按实际类型推导出类型,使用自动推导类型,反之,如果无法自动推导,则使用默认模板参数:
来自于C++11标准草案的例子:
template <class T, class U = double> 
void f(T t = 0, U u = 0);  
 
void g() {  
    f(1, 'c');      // f<int,char>(1,'c')  参数二自动推导
    f(1);           // f<int,double>(1,0), 使用了默认模板参数double  
    f();            // 错误: T无法被推导出来  
    f<int>();       // f<int,double>(0,0), 使用了默认模板参数double  
    f<int,char>();  // f<int,char>(0,0)  
}  
// 编译选项:g++ -std=c++11 2-11-3.cpp  


 
参考:http://book.51cto.com/art/201306/400328.htm
C++ Primer
深入应用C++ 11













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值