Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4513235
  • 博文数量: 356
  • 博客积分: 10458
  • 博客等级: 上将
  • 技术积分: 4734
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-24 14:59
文章分类

全部博文(356)

文章存档

2020年(17)

2019年(9)

2018年(26)

2017年(5)

2016年(11)

2015年(20)

2014年(2)

2013年(17)

2012年(15)

2011年(4)

2010年(7)

2009年(14)

2008年(209)

分类: C/C++

2008-05-11 17:33:42

template
int FOO(T, const U*)
{return 1;}

template <>
int FOO(int, const char*)
{return 12;}

const char* b;
    cout << FOO(1, b) << endl;

结果是啥?

template
int FOO(T, const U*)
{return 1;}

template <>
int FOO(int, const char* const*)
{return 12;}

    const char* b;
    cout << FOO(1, &b) << endl;

结果是啥?

template
int FOO(T, U)
{return 1;}

template <>
int FOO(const int, const char*)
{return 12;}

const char* b;
    cout << FOO(1, b) << endl;

又是啥

 

/***********************************************************
示例1:
***********************************************************/
/*baihacker , devc++*/
#include
using namespace std;
/*
模板0:
*/
template
int FOO(T, const U*)
{return 1;}

/*
模板1:
用int, const char 实例化模板,得到
FOO (int, const char*)
*/
template <>
int FOO(int, const char*)
{return 2;}

/*
模板2:
参数是int , const char*
推测出是用int, char 实例化模板
*/
template <>
int FOO(int, const char*)
{return 3;}

/*
参数是int, char*
无法推测出是实例化哪个模板,error
template <>
int FOO(int, char*)
{return 3;}
*/

/*普通函数,优先级最高*/
int FOO(int, const char*)
{return 4;}

int main()
{
    const char* b;
    /*
    参数是int , const char*
    推测出是用int, char 实例化模板
    */
    cout << FOO(1, b) << endl;
    /*
    结果为4,因为普通函数最高
    去掉这个普通函数,结果为3,根据参数推测到使用FOO template with T = int, U = char
   
    只保留模板0,1,结果为1
    根据参数推测到使用 FOO template with T = int, U = char,虽然
    第二个函数的参数是int, const char* 但是使用的是 FOO template with T = int, U = const char
    故不调用第二个函数
    由于const const char* 还是const char*,所以对于这个参数,并强制使用模板  
    FOO template with T = int, U = const char 是没有错误的
    问题:什么时候才可能调用第二个模板 ?
   
    如果把<>内的const去掉,则   
    template <>
    int FOO(int, const char*)
    {return 2;}

    template <>
    int FOO(int, const char*)
    {return 3;}
    等价,同时出现一个重复定义的错误
    */
    cin.get();
 return 0;
}


/***********************************************************
示例2:
***********************************************************/
/*baihacker , devc++*/
#include
using namespace std;
/*
模板0:
*/
template
int FOO(T, const U*)
{return 0;}

/*
模板1:
*/
template <>
int FOO(int, const char* const *)
{return 1;}

/*
模板2:
*/
template
int FOO(T, U*)
{return 2;}

/*
模板3:
*/
template <>
int FOO(int, char*)
{return 3;}


int main()
{
    const char* b;
    cout << FOO(1, &b) << endl;
    /*推测出来使用模板2, 这个 匹配度最高
    去掉模板2,3后调用模板1*/
    cin.get();
    return 0;
}
 
结论:
template<>
int FOO(...);
是根据参数选择模板全特化

template<>
int FOO<...>(...);
全特化模板,并根据参数匹配模板检查

调用的时候根据参数确定T,U,然后再调用特别注意示例1中
FOO template with T = int, U = const char
FOO template with T = int, U = char
在参数上表现相同
但是是不同的模板!

补充一点:
特化最好使用
template<>
int FOO<...>(...);
这样使得编译器不太累,让你看起来也不累
否则有时连你都不知道推测出来使用的是什么模板,结果特化无效

template <>
int FOO(int, const char* const *)
{return 123;}

template <>
int FOO(int, const char* const *)
{return 123;}
上面两个等价,但是用<>可以更好地指明模板中T和U是什么

 

/***********************************************************
示例3:
***********************************************************/
/*baihacker , devc++*/
#include
using namespace std;

/*
模板0:
*/
template
int FOO(T, U)
{return 1;}

/*
模板1:
    FOO template with T = const int, U = const int
*/
template <>
int FOO(const int, const int)
{return 2;}

/*
模板2:
    FOO template with T = int, U = int
*/
template <>
int FOO(const int, const int)
{return 3;}

int main()
{
    const int a = 1;
    const char* b;
    cout << typeid(b).name() << endl;
    cout << FOO(a, a) << endl;//参数本身的类型是int故 FOO template with T = int, U = int
    cout << FOO(1, 1) << endl;//参数本身的类型是int故 FOO template with T = int, U = int
    cin.get();
 return 0;
}
    /*
        const 是类型限定符(另一个是volatile)
        a的类型是int
        1的类型也是int
        const char* a 的 类型是 char const * (和const char * 等价)
        char * const a的 类型是 char*
        所以一个const作用在一个普通类型,const并不作为类型的一部分
        只有const来修饰指针指向的内容的时候 才作为类型的一部分
        const修饰的参数的可以接受非const的变量
        char const* const *为函数参数类型
        char const * b :&b的类型是 char const * * 指向一个指向常字符串的指针
                        char const* const *的类型是一个指向常字符串的常量指针
        所以 char const* const *能接受&b
       
        在这里如果直接使用模板1
        那么结果不是你所期望的
        所以最好使用
       
        模板1:
            FOO template with T = int, U = int

        template <>
        int FOO(const int, const int)
        {return 2;}
       
        让编译器推导使用哪个模板
        和前面的文章分析结果相反
        建议:
            在简单类型,含const时使用自动推导
            在有指针的时候,最好直接指明
    */


/*示例4 来自csdn的问题*/
/*devc++*/
#include 
#include 
using namespace std;

typedef char* PCHAR ;

void TestFunc(const PCHAR & pConstRef)
{
 PCHAR ptr1 = pConstRef;
 const char *ptr2 = pConstRef;
 cout <<"pConstRef 's Type:"  << typeid(pConstRef).name()  << endl;
 cout <<"ptr1 's Type: "  << typeid(ptr1).name()  << endl;
 cout <<"ptr2 's Type: "  << typeid(ptr2).name()  << endl;
   //*ptr1 = 'a';
}

template
void TestFunc2(const T & pConstRef)
{
 T var1 = pConstRef;
 const T var2 = pConstRef;
 cout <<"pConstRef 's Type:"  << typeid(pConstRef).name()  << endl;
 cout <<"var1 's Type: "  << typeid(var1).name()  << endl;
 cout <<"var2 's Type: "  << typeid(var2).name()  << endl;
}

int main(int argc, char *argv[])
{
 char pBuf[100] = "suntao";
 char* pNonConst = pBuf;
 TestFunc (pNonConst);
 TestFunc2 (pNonConst);
 cin.get();
 return EXIT_SUCCESS;
}
    /*
        结果是TestFunc2内的var2类型不同
        先分析一下:
        TestFunc:
        const PCHAR & pConstRef
        去掉pContsRef,去掉&得到 pConstRef的类型是 const PCHAR
        const规则:const PCHAR = PCHAR const
        注意到 typedef char* PCHAR ;
        const char* = char* const
        所以const PCHAR & pConstRef只是保证pConstRef不变 
        ptr1, ptr2的类型显然
       
        对于 TestFunc2所有的类型显然
       
        typedef char* PCHAR ;
        const PCHAR  var1;
        const char * var2;
        =>var1 和 var2是不同的类型
       
        所以在使用模版的时候要注意!
    */

阅读(2540) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~