std::max 函数 VS '>' 运算符中 int 和 long long int 之间的最大值

Maximum between int and long long int inside std::max function VS '>' operator

我有两个 long long int 向量 "a" 和 "b",我希望将 "a" 和 "b" 各自元素的差异放入一个向量 "c"。但我不希望这些差异低于 0。

#include<bits/stdc++.h>
using namespace std;

int main(){
    vector<long long int> a={360757931684,484141693549}; 
    vector<long long int> b={186119101678,675563431537};
    vector<long long int> c; 
    vector<long long int> d;

    for (int i=0; i<2; i++){
        // c.push_back(max(0,a[i]-b[i]));
        c.push_back(max(0ll,a[i]-b[i]));
        //I need to use "0ll" to make this work, Because the commented line above doesn't work
    }
    for (int i=0; i<2; i++){
        if (a[i]-b[i]>0)
            //Here this works fine even without "0ll"
            d.push_back(a[i]-b[i]);
        else
            d.push_back(0);
    }
    return 0;
}

在使用 std::max 函数时我不得不使用 0ll,但是在使用 > 运算符时仅使用 0 就足够了。为什么?

那是因为 std::max 必须给出两个完全相同类型的参数,而 intlong long int 是两个不同的类型。如果你写std::max(0, a[i]-b[i]),编译不通过,因为a[i]-b[i]的类型是long long int,而0的类型是int.

更长的答案:

std::max是函数模板。您正在使用的重载具有一个模板参数 T 和两个参数 const T& aconst T& b。当你调用std::max时,你可以像这样显式指定模板参数。

std::max<long long int>(0, a[i]-b[i])

在这种情况下,编译器将生成一个接收两个 long long int 的函数,实际上您可以将任何可转换为 long long int 的内容传递给该函数。

但是,如果您不指定模板参数 Ttemplate argument deduction 将尝试为您推导它。

这是它的工作原理。第一个参数是 const T& a,因此编译器会根据您作为参数传递的内容尝试推断出 T。您传递 0,因此编译器推断 T 是一个 int

然后编译器尝试使用第二个参数const T& b 推导T。您传递了 long long int,因此编译器推断 T 必须是 long long int.

编译器无法实例化函数模板,因为它为同一模板参数推导了冲突的类型。

无法使用指定参数实例化函数模板 std::max,编译器无法找到要调用的匹配函数,这就是您收到编译错误的原因。