Chinaunix首页 | 论坛 | 博客
  • 博客访问: 323038
  • 博文数量: 100
  • 博客积分: 2620
  • 博客等级: 少校
  • 技术积分: 920
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-16 02:50
文章分类

全部博文(100)

文章存档

2011年(5)

2010年(12)

2009年(83)

分类:

2009-12-05 17:35:11


模板特化

这里只针对函数模板讨论一下模板匹配的问题。
参考链接:
一下的代码如果没有说明,都是从以上连接里面拷贝过来的。
#include
using namespace std;
//base
template
    void func (const T &v1, const T &v2) {
        cout<<"template"<    }
//A
template <>
    void func (char* const  &v1, char* const  &v2) {
        cout<<"Specialization: char*"<    }
  
//B    
template <>
    void func (const char* const  &v1, const char* const  &v2) {
        cout<<"Specialization: const char*"<    }
   
//C
template <>
    void func ( char const (&v1)[6],  char const (&v2)[6]) {
        cout<<"Specialization: const char[6]"<    }
//D
template <>
    void func ( char const (&v1)[6],  char const (&v2)[6]) {
        cout<<"Specialization: char[6]"<    }
   
int main()
{
    char *p1 = "hello";
    char *p2 = "world";
    func(p1, p2); //Specialization: char* (1)
       
    char * const p3 = "hello";
    char * const p4 = "world";
    func(p3, p4); //Specialization: char* (2)
   
    const char *p5 = "hello";
    const char *p6 = "world";
    func(p5, p6); //Specialization: const char* (3)
       
    const char * const p7 = "hello";
    const char * const p8 = "world";
    func(p7, p8); //Specialization: const char* (4)
   
    char a1[6] = "hello";
    char a2[6] = "world";
    func(a1, a2); //Specialization: char[6] (5)
       
    const char a3[6] = "hello";
    const char a4[6] = "world";
    func(a3, a4); //Specialization: char[6] (6)
       
    return 0;
}
解释:
1.首先A,B,C,D都是模板base的特化版本,而且特化版本需要再base之后声明。有一点base是基类,特别模板是派生类的感觉。
2.A,B,D都可以看做是base中的T替换掉特换版本中的type得来,但是C却不是,原因见注1。
3. 推导应该使用的特化版本时,将采用最精确的版本。
(1)是匹配A而来,其实这还不是最精确匹配,只是char* 可以匹配const char*而已,如果再加一个模板base2和特别版本如下:
//base2
   template
   void func (T &v1, T &v2) {
           cout<<"template"<   }
//A2
   template <>
   void func (char* &v1, char* &v2) {
           cout<<"Specialization: char*"<   }
此时,(1)将匹配到A2,而不是A,因为A2更精确。
另外,如果只是加一个A2,而不加base2是不正确的,因为从base1不能推导出A2。
注1:一点模板参数推导规则
推导规则1:“The top-level cv-qualifiers on the template-parameter are ignored when determining its type.” 指
toplevel限定符再模板参数推导的时候会被忽略掉,const char arr[]中,const就是top-level限定符;const char* const pValue
中,第二个const才是top-level限定符。他们再模板参数推导的时候都会被忽略掉。
推导规则2:“const转换:接受const引用或const指针的函数可以分别用非const对象的引用或指针来调用,而无须产生新的实例化。

4.(2)通过模板规则1后,变得和(1)情况一样。
5.(3)类型为const char*正好匹配B。
6.(4)模板规则1
7.(5)类型为char [6],匹配D
8.(6)模板规则1
//另一段代码
#include
using namespace std;
template
    void func (T &v1, T &v2) {
        cout<<"template"<    }
         
template <>
    void func (const char* &v1, const char* &v2) {
        cout<<"Specialization: const char*"<    }
       
template <>
    void func (char (&v1)[6], char (&v2)[6]) {
        cout<<"Specialization: char[6]"<    }
   
int main()
{
    const char * p1 = "hello";
    const char * p2 = "world";
    func(p1, p2);  //Specialization: const char*
   
    const char * const p3 = "hello";
    const char * const p4 = "world";
    func(p3, p4); //template
   
    char a1[6] = "hello";
    char a2[6] = "world";
    func(a1, a2); //Specialization: char[6]
       
    const char a3[6] = "hello";
    const char a4[6] = "world";
    func(a3, a4); //template
       
    return 0;
}
(whyglinux 的)解释:
模板参数推导的前提条件是首先函数的签名特征要符合。在上面给出的第一个例子中,p1、p2、a1、a2 等变量都不是 const 限定的
,而 a3、a4、p3、p4 都是 const 限定的(这样的 const 就是一个 top-level 限定符);而你给出的两个特化函数的参数不是
const 引用的形式,所以如果用 a3、a4 或者 p3、p4 等 const 限定的变量来作为函数参数的话是不可能与这两个特化函数相匹配
的,所以对这两个特化函数进行模板参数推导也就没有必要了。
阅读(987) | 评论(0) | 转发(0) |
0

上一篇:const char*

下一篇:Mangos 之 AuthSocket模块

给主人留下些什么吧!~~