LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 867|回复: 1

C++ PRIMER问题之重载函数模板解析。

[复制链接]
发表于 2003-9-4 10:51:27 | 显示全部楼层 |阅读模式
1>
P430:

template    < typename  Type>
    Type   sum ( Type * , int );

template    < typename  Type>
    Type   sum ( Type , int );

int  ia[1024];

int   ival1 = sum < int > ( ia , 1024 );

举此例之前有:(书中原文):“即使对于一个函数调用,两个不同的函数模板都可以实例化,但该函数调用 仍然不是二义的”。然后举了上述例子加以说明。

我认为 sum 函数调用只能用第一个模板产生实例,第二个模板并不是它的“可行函数”,而上述一段话中为什么又讲这两个不同的函数模板都可以实例化呢?


2>
template  < class  Type>
  Type  sum  (Type , int )  {   }

template  <  >  double  sum <double>  ( double , int );

void  manip ( double  ii,  double dd )
{
    sum ( dd, ii);
}

如果有一个普通函数(没有模板函数)如:double  sum (doluble , int );
则 sum ( dd, ii);会被调用,ii 被转化为 int ,上述模板的特化也能同样被调用吗(有或没有普通函数的两种情况下)?如果是调用 " sum <double> ( dd, ii) // 显示模板实参 " 呢?  


3>
P433:

template <class T> T min ( T, T);
int min ( int , int ) {  }
int ai[4] = { 0 };
int main () {
    min (ai[0], 99 ); }
// 这样的调用不是二义的, 因为非模板函数存在时,因为该函数被显示实现,所以它被给予更高的优先级。  (这一句话是书上原文)

P435:

template  < class Type>
  Type  max ( Type , Type ) {  .. .  . }
double max (double , double );

int main () {
  double  dval;
  max ( 0.25, dval );
}
//因为调用两个函数都完全匹配,所以该调用存在二义。( 引用书上原文)

问题:为什么一个有二义,一个没有二义?它们是一样的意思啊。
虽然最后调用的都是普通函数,但为什么一个有二义,一个没有呢?
发表于 2003-9-4 21:24:32 | 显示全部楼层

回复: C++ PRIMER问题之重载函数模板解析。

看你提的几个都是用模板进行函数重载的几个例子。
最初由 Andy84920 发表
1>
P430:

template    < typename  Type>
    Type   sum ( Type * , int );

template    < typename  Type>
    Type   sum ( Type , int );

int  ia[1024];

int   ival1 = sum < int > ( ia , 1024 );

举此例之前有:(书中原文):“即使对于一个函数调用,两个不同的函数模板都可以实例化,但该函数调用 仍然不是二义的”。然后举了上述例子加以说明。

我认为 sum 函数调用只能用第一个模板产生实例,第二个模板并不是它的“可行函数”,而上述一段话中为什么又讲这两个不同的函数模板都可以实例化呢?


还是看英文原版吧,翻译过来的总是容易误解。

  1. template <typename Type>
  2.        Type sum( Type*, int );
  3. template <typename Type>
  4.        Type sum( Type, int );
  5. int ia[1024];
  6. // Type == int ; sum<int>( int*, int );                   or
  7. // Type == int*; sum<int*>( int*, int );                  ??
  8. int ival1 = sum<int>( ia, 1024 );
  9. Surprisingly enough, the preceding call is not ambiguous. The template is instantiated using the first
  10. template definition. The template definition that is the most specialized is chosen for the instantiation. The
  11. template argument for Type is therefore int and not int*.
复制代码


上面是原文,int   ival1 = sum < int > ( ia , 1024 ) 很显然使用的是第一个模板定义。能根据传递的参数决定使用相应的模板。

2>
template  < class  Type>
  Type  sum  (Type , int )  {   }

template  <  >  double  sum <double>  ( double , int );

void  manip ( double  ii,  double dd )
{
    sum ( dd, ii);
}

如果有一个普通函数(没有模板函数)如:double  sum (doluble , int );
则 sum ( dd, ii);会被调用,ii 被转化为 int ,上述模板的特化也能同样被调用吗(有或没有普通函数的两种情况下)?如果是调用 " sum <double> ( dd, ii) // 显示模板实参 " 呢?  


书上没找到原文,只找到下面一段:
  1. // function template definition
  2. template <class Type> Type sum( Type, int ) { /* ... */ }
  3. // explicit specialization for Type == double
  4. template<> double sum<double>( double,int );
  5. // ordinary (nontemplate) function
  6. double sum( double, double );
  7. void manip( int ii, double dd ) {
  8.         // calls template explicit specialization sum<double>()
  9.         sum( dd, ii );
  10. }

  11. For the call to sum() in manip(), template argument deduction finds that the instantiation sum
  12. (double,int) generated from the generic template definition should be entered into the set of
  13. candidate functions. However, an explicit specialization is provided for sum(double,int), and it is this
  14. explicit specialization that is entered into the set of candidate functions. In fact, because this specialization
  15. is later found to be the best match for the call, it is the function that is selected by function overload
  16. resolution.
复制代码

大意是 manip() 调用了 sum(),模板参数演绎机制发现对于要通过泛型模板定义创建的实例 sum(doubel,int) 有一组有供选择的候选函数,我们可以看到 sum( dd, ii)  中 dd 是 double 型,ii 是 int 型,而函数模板 sum<double> (doubel, int) 很清楚的提供了这种特殊性,所以它是最佳候选人,被重载函数选择。

3>
P433:

template <class T> T min ( T, T);
int min ( int , int ) {  }
int ai[4] = { 0 };
int main () {
    min (ai[0], 99 ); }
// 这样的调用不是二义的, 因为非模板函数存在时,因为该函数被显示实现,所以它被给予更高的优先级。  (这一句话是书上原文)

没错,int min (int, int) 显然不匹配,优先调用模板。很奇怪,你看的是谁翻译的书呀,语句都不通顺呀!

P435:

template  < class Type>
  Type  max ( Type , Type ) {  .. .  . }
double max (double , double );

int main () {
  double  dval;
  max ( 0.25, dval );
}
//因为调用两个函数都完全匹配,所以该调用存在二义。( 引用书上原文)

问题:为什么一个有二义,一个没有二义?它们是一样的意思啊。
虽然最后调用的都是普通函数,但为什么一个有二义,一个没有呢?


翻译的没错,模板和普通函数参数相似,编译器没法识别,不知道该调用哪个,所以该定义存在二义性。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表