显式模板参数规范

时间:2012-12-04 10:48:40

标签: c++ templates

我开始阅读模板,我对下面的内容感到困惑。

template<class T>
T max(T t1, T t2)
{
   if (t1 > t2)
      return t1;
   return t2;
}

int main(){
   std::cout<<max<int>(120,14.55);
   return 0;
}

输出是120.但是当我编译上面的内容时,我得到了这个警告:

warning:passing double for argument 2 to T max(T, T) [with T = int].

我的问题是为什么会出现这个警告,因为我已经为T max(int t1,double t2)实例化了。

因为根据我的理解,如果我只明确提到一种数据类型(这里是int),编译器会从参数类型(14.55)中扣除其他数据类型。这意味着T max(T t1, T t2)在这种情况下实例化T max(int t1,double t2)。我从互联网上的一些模板文档中读到了这个概念。

请清除我的疑虑,否则我无法继续前进。

3 个答案:

答案 0 :(得分:2)

您的特定模板只有一个模板参数T。这意味着max<int>创建了这个:

int max(int t1, int t2)

无法从此模板中生成max(int, double)。如果您想要混合类型参数,模板必须如下所示:

template <typename T1, typename T2>
/*some return type*/ max(T1 t1, T2 t2)

但是,现在确定返回类型应该是不容易的,并且可能需要type_traits来为这样的函数导出正确的返回类型。

答案 1 :(得分:1)

std::cout << max<int>(120,14.55);

此行与使用函数相当 int max(int,int),因此编译器会发出从14.55到14的转换警告 - 可能会丢失数据。

如果要比较不同类型的数据,则应使用

template<class T, class T1, class T2>
T max(T1 t1, T2 t2)
{
   if (t1 > t2)
      return T(t1);
   return T(t2);
}

稍后在main.cpp中:

float a = max<float, int, double>(10, 11.0);

但这不是最佳方式。

答案 2 :(得分:0)

  

为什么发出这个警告是我的问题,因为我已经为T max(int t1,double t2)实例化了。

不,你没有。提供int作为模板参数,通过用int替换参数的所有出现来实例化模板:

T max(T t1, T t2)    becomes    int max(int t1, int t2)
  

因为按照我的理解,如果我只明确提到一种数据类型(这里是int),其他的将从参数类型中扣除

没有。您的模板只有一个参数,用于两个函数参数类型;因此,如果您指定该参数,那么它将用于两者(以及返回类型)。如果您希望单独对它们进行参数化,那么每个都需要一个单独的参数。

template <typename T1, typename T2>
???? max(T1 t1, T2 t2)

如何最好地指定返回类型作为练习。

现在,如果你只提供第一个参数,那么第二个参数是从第二个函数参数推导出来的:

max<int>(120,14.55);  // T1=int given, T2=double deduced -> max(int,double)
max(120,14.55)        // T1=int, T2=double both deduced  -> max(int,double)