C++ 模板类型背后的含义是什么?

C++ 模板类型背后的含义是什么?,c++,c++11,templates,raw-types,C++,C++11,Templates,Raw Types,通过使用模板: template <class T> T GetMax (T a, T b) { return (a>b?a:b); } 这是为什么 n=GetMax<double>(l,m); n=GetMax(l,m); 当l和m是与双精度大不相同的整数时?可以忽略模板函数上的类型,因为它们在编译时会被扣除 第二个问题是,没有错误,因为整数可以很好地回退到double,所以它们将被转换并用作模板逻辑上的double。在这种情况下,您可以认为模

通过使用模板:

template <class T>
T GetMax (T a, T b) {
  return (a>b?a:b);
}
这是为什么

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

lm是与双精度大不相同的整数时?

可以忽略模板函数上的类型,因为它们在编译时会被扣除


第二个问题是,没有错误,因为整数可以很好地回退到double,所以它们将被转换并用作模板逻辑上的double。

在这种情况下,您可以认为模板实例化是一种简单的文本替换(离它不远),也就是说,一旦您确定了模板参数。因此:

  • 让编译器从操作数中找出类型。由于它们匹配,
    T
    被计算为
    int
    。您可以在标准中找到匹配模板参数排名的确切逻辑。你的情况很简单 在计算出模板参数后,进行替换,因此您的函数如下所示:

    int GetMax (int a, int b) {
       return (a>b?a:b);
    }
    
    当您使用多个参数并且与继承等有许多可能的匹配时,它确实会被编译

    对于您的情况,您可以通过对参数使用两种不同的类型,即:
    GetMax(i,l)
    来激发相同的匹配
    T
    有两个候选项:
    double
    as
    int
    ,两者都一样好

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

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

  • double
    中显式声明T。同样,编译器不会调用与类型有关的任何逻辑

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

     double GetMax (double a, double b) {
        return (a>b?a:b);
     }
    
    使用
    double
    int
    传递给函数是合法的,会发生隐式转换

    这是完全合法的:

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


    确定模板类型与调用函数是不同的逻辑。将其视为单独的阶段。类型推断是为了使调用有意义而设计的,但它是另一回事。

    为什么我需要这样做?
    :您不需要<代码>为什么编译?:
    T
    已设置为
    long
    long
    可隐式转换为
    double
    。这与做
    double v=m相同作为一个小的补充:如果参数是不同类型的(例如,
    getMax(i,l)
    ),自动类型推断将失败,您将得到一个编译器错误。在这种情况下,您需要以某种方式使类型显式以使其可编译(通过将参数强制转换为公共类型或通过显式指定模板类型,就像您在案例2和案例3中所做的那样)。是的,因为有两种可能的候选者同样适合替换。我将编辑1。更重要的是,如果我在调用GetMax(a,b)时使用ommit,是否正确??
    int GetMax (int a, int b) {
       return (a>b?a:b);
    }
    
     double GetMax (double a, double b) {
        return (a>b?a:b);
     }
    
    void f(double d) {};
    
    int main(){
        int i = 5;
        f(i);
    }