请教一个模板的小问题

时间:2022-12-09 17:35:42
#include <iostream.h>

template <class T> T max(T a, T b)
{
return a>b?a:b;
}

void main()
{
cout<<max('H', 'G')<<endl;
cout<<max("H", "G")<<endl;
}

以上程序第一行输出H, 但第二行输出G, 怎么理解?

12 个解决方案

#1


是这样的:第一个cout<<max('H', 'G')<<endl; 程序回生成一个char max(char ,char)型的函数
第二个cout<<max('H', 'G')<<endl;程序回生成一个char* max(char* ,char*)型的函数
我发现 “H”"G"的地址分别为:0x0042501c 
和 0x00425020 这样当然是后者大了。

#2


但是
void main()
{
char* a="H";
char* b="G";
cout<<max(a, b)<<endl;
}
结果却是H, 又该怎么理解?

#3


我在VC下面结果都是 H .

#4


"H"这种表示法是字符串的表示法,因此在调用max()时,T是const char *,a > b比较的是字符串的地址,这种情况应该用模板的特殊化:

template<> const char * max<const char *>(const char *a, const char *b)
{
    return strcmp(a,b) > 0 ? a : b;
}

#5


Kidsheep(Kidsheep)  补充得很对!!!!!!!

#6


楼上的:
    template<> const char * max<const char *>(const char *a, const char *b)
中的template<>的参数为何不用了?而max后面咋又多了一个<const char *>???
这和我昨天至今弄不清楚的一个C++的类模板问题有点象:
书上是这样定义的: 模板 <模板参数表> 对象名1 .... 对象名n;
而它给出的例子中:

struct Student 
{
  int id;
  float gpa;
};

template<class T>
class Store
{
private:
  T item;
  int haveValue;
public:
  Store(void)  //默认构造函数;
  T GetElem(void) //提取数据
  void PutElem(T x) //存入数据
};

//默认构造函数的实现
template<class T>
Store<T>::Store(void):haveValue //这里不明白了:(
{}

//提取数据函数的实现
template<class T>
T Store<T>::GetElem(void)  //不明白....昏倒:((
{
  .....
}

......

#7


1.你的机器上,堆栈空间是自顶向下生长的。就是说,先入栈的变量地址要大于后入栈变量的地址。
2.函数的调用约定默认为__cdecl,这时,函数参数的入栈顺序为从右往左。
3.如果想要max函数对于char*也能处理正确,请增加max函数针对char*, const char*的特化版本。

#8


szgod() ,
模板的语法就是这样的,刚开始看这是有点怪,等你习惯了,就好了。

#9


to xiaoyunet(快乐的小猪):
   字符串常量存放在内存data区的const区, 又怎么会涉及到入栈呢
另外你不觉得 
cout<<max("H", "G")<<endl;结果是G

char* a="H";
char* b="G";
cout<<max(a, b)<<endl;
结果是H
矛盾吗

#10


我弄错了,这里的确和参数的入栈顺序无关。

另外,在我的机器上测试,两个的返回值都是"G",我的编译环境为vc7.1。

我认为,不同的编译器的做法不同,所以返回的可能是“H”,也么能使"G",这要看这两个常量在内存中具体的地址大小。

编译器对于常量有以下的优化:如果两个常量的值相同,则只存在一个副本。所以不管你是直接写"H"也好,写char* p = "H"也好,都只有一个"H",你的p就指向这个"H"的地址。所以两次max的返回值应该是一样的,不过,如果编译器没有做这个优化的话,结果就难讲了。

#11


我觉得
97<98
所以,两个的结果都应该是  G

#12


看了各位的结果,自己再试:
#include <iostream.h>
template <class T> 
T max(T a, T b)
{
return a>b?a:b;
}

void main()
{
cout<<max('H', 'G')<<endl;
cout<<max("H", "G")<<endl;
char* a="H";
char* b="G";
cout<<max(a, b)<<endl;
}
输出;
H
H
G

晕啊!
偶用的.NET,难道是编译器不同造成的?

#1


是这样的:第一个cout<<max('H', 'G')<<endl; 程序回生成一个char max(char ,char)型的函数
第二个cout<<max('H', 'G')<<endl;程序回生成一个char* max(char* ,char*)型的函数
我发现 “H”"G"的地址分别为:0x0042501c 
和 0x00425020 这样当然是后者大了。

#2


但是
void main()
{
char* a="H";
char* b="G";
cout<<max(a, b)<<endl;
}
结果却是H, 又该怎么理解?

#3


我在VC下面结果都是 H .

#4


"H"这种表示法是字符串的表示法,因此在调用max()时,T是const char *,a > b比较的是字符串的地址,这种情况应该用模板的特殊化:

template<> const char * max<const char *>(const char *a, const char *b)
{
    return strcmp(a,b) > 0 ? a : b;
}

#5


Kidsheep(Kidsheep)  补充得很对!!!!!!!

#6


楼上的:
    template<> const char * max<const char *>(const char *a, const char *b)
中的template<>的参数为何不用了?而max后面咋又多了一个<const char *>???
这和我昨天至今弄不清楚的一个C++的类模板问题有点象:
书上是这样定义的: 模板 <模板参数表> 对象名1 .... 对象名n;
而它给出的例子中:

struct Student 
{
  int id;
  float gpa;
};

template<class T>
class Store
{
private:
  T item;
  int haveValue;
public:
  Store(void)  //默认构造函数;
  T GetElem(void) //提取数据
  void PutElem(T x) //存入数据
};

//默认构造函数的实现
template<class T>
Store<T>::Store(void):haveValue //这里不明白了:(
{}

//提取数据函数的实现
template<class T>
T Store<T>::GetElem(void)  //不明白....昏倒:((
{
  .....
}

......

#7


1.你的机器上,堆栈空间是自顶向下生长的。就是说,先入栈的变量地址要大于后入栈变量的地址。
2.函数的调用约定默认为__cdecl,这时,函数参数的入栈顺序为从右往左。
3.如果想要max函数对于char*也能处理正确,请增加max函数针对char*, const char*的特化版本。

#8


szgod() ,
模板的语法就是这样的,刚开始看这是有点怪,等你习惯了,就好了。

#9


to xiaoyunet(快乐的小猪):
   字符串常量存放在内存data区的const区, 又怎么会涉及到入栈呢
另外你不觉得 
cout<<max("H", "G")<<endl;结果是G

char* a="H";
char* b="G";
cout<<max(a, b)<<endl;
结果是H
矛盾吗

#10


我弄错了,这里的确和参数的入栈顺序无关。

另外,在我的机器上测试,两个的返回值都是"G",我的编译环境为vc7.1。

我认为,不同的编译器的做法不同,所以返回的可能是“H”,也么能使"G",这要看这两个常量在内存中具体的地址大小。

编译器对于常量有以下的优化:如果两个常量的值相同,则只存在一个副本。所以不管你是直接写"H"也好,写char* p = "H"也好,都只有一个"H",你的p就指向这个"H"的地址。所以两次max的返回值应该是一样的,不过,如果编译器没有做这个优化的话,结果就难讲了。

#11


我觉得
97<98
所以,两个的结果都应该是  G

#12


看了各位的结果,自己再试:
#include <iostream.h>
template <class T> 
T max(T a, T b)
{
return a>b?a:b;
}

void main()
{
cout<<max('H', 'G')<<endl;
cout<<max("H", "G")<<endl;
char* a="H";
char* b="G";
cout<<max(a, b)<<endl;
}
输出;
H
H
G

晕啊!
偶用的.NET,难道是编译器不同造成的?