模板类型背后的意义是什么?

时间:2017-04-11 09:56:44

标签: c++ c++11 templates raw-types

使用模板:

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

然后

int main () {
  int i=5, j=6, k;
  long l=10, m=5, n;
  k=GetMax(i,j);           // line 1
  n=GetMax<int>(l,m);      // line 2
  n=GetMax<double>(l,m);   // line 3
  cout << k << endl; 
  cout << n << endl;
  return 0;
}

我的问题是:

为什么我需要这样做:

n=GetMax<int>(l,m);      // line2

如果我能做到

n=GetMax(l,m);      // line 2

为什么这会编译?

n=GetMax<double>(l,m);     

l m 是一个远离双重的整数时?

2 个答案:

答案 0 :(得分:3)

在这种情况下,您可以认为模板即时化是一个简单的文本替换(距离它不远),即一旦您找到了模板参数。所以:

  1. 让编译器从操作数中找出类型。由于匹配,T被认为是int。您可以在标准中找到排序匹配模板参数的确切逻辑。你的情况非常简单。
  2. 在确定模板参数之后,进行替换,因此您的函数如下所示:

    int GetMax (int a, int b) {
       return (a>b?a:b);
    }
    

    当您使用多个参数并且具有许多可能的继承匹配等时,它确实会被编译。

    对于你的情况,你可以通过使用两种不同类型的参数来激发相等的匹配,即:GetMax(i,l)T有两个候选人:doubleint,两者都同样出色。

    这与着名的SFINAE有关(替换失败不是错误)。编译器尝试为可能的参数组合生成版本,如果失败,则不考虑最终排名。在你的情况下,两次换人成功。

    1. 您明确声明T为int。因此编译器不会调用自动参数匹配。实例化版本看起来与1相同。

    2. 您在double中明确说明了T.同样,编译器不会调用有关类型的任何逻辑。

    3. 盲目地为double生成版本,并使用它:

       double GetMax (double a, double b) {
          return (a>b?a:b);
       }
      

      使用intdouble传递给函数是合法的,会发生隐式转换。

      这是完全合法的:

      void f(double d) {};
      
      int main(){
          int i = 5;
          f(i);
      }
      

      底线:

      确定模板类型是一个不同于调用函数的逻辑。将其视为单独的阶段。类型推导被设计为对调用有意义,但它是一个单独的东西。

答案 1 :(得分:0)

您可以省略模板函数的类型,因为它们是在编译时扣除的

第二个问题,没有错误,因为整数回退优雅地加倍,所以它们将被转换并在模板逻辑上用作double。

相关问题