Why can't compare int and size_t in c++

The thing is that if I compare int and size_t in for loop it works fine.

vector<int> v;
for (int i = 0; i < v.size(); ++i)

However, it doesn't work if I do this:

vector<int> v;
int max_num = max(3, v.size());
Line 13: Char 24: error: no matching function for call to 'max'

/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/algorithmfwd.h:370:5: note: candidate template ignored: deduced conflicting types for parameter '_Tp' ('int' vs. 'unsigned long')
    max(const _Tp&, const _Tp&);
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:3462:5: note: candidate template ignored: could not match 'initializer_list<type-parameter-0-0>' against 'int'
    max(initializer_list<_Tp> __l, _Compare __comp)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:3456:5: note: candidate function template not viable: requires single argument '__l', but 2 arguments were provided
    max(initializer_list<_Tp> __l)
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/algorithmfwd.h:375:5: note: candidate function template not viable: requires 3 arguments, but 2 were provided
    max(const _Tp&, const _Tp&, _Compare);
    ^
1 error generated.

In the bottom case, I have to cast size_t into int to make it works.

Why in the for loop I don't need to do that? Just curiouos.


In C++ when the types of a binary operator are different, there are various (complicated) rules that govern what actual type the binary operator uses:

i < v.size()

One of these is an int. The other one is a size_t. This is ok, there are rules that figure out which actual type is used for the comparison (the int value gets type-converted to size_t, then the < operator does the comparison.

max(3, v.size());

The definition of std::max functionally requires both of its parameters to be the same type. They're not. Hence the compilation error.

Now that you understand the reason, try to reread the following error message, and see if you now understand the compiler telling you exactly that:

deduced conflicting types for parameter '_Tp' ('int' vs. 'unsigned long') max(const _Tp&, const _Tp&);

As you can see here, the compiler is trying very hard to digest a function with two parameters, both of which are the same type: const _Tp &. That's how max()'s definition reads: both of its parameters are the same type.

Well, the poor compiler sees that one of these parameters is an int, the other one is size_t (a.k.a. "unsigned long") and gives up.