Suppose you have a function f that returns a double, and you want to store in a variable the value of this function, if this a positive number, or zero if the return value is negative. This line of C++ code tries to do that:
double x = std::max(0, f(/* something */));
Unfortunately, this apparently innocent code won’t compile!
The error message produced by VS2015’s MSVC compiler is not very clear, as often with C++ code involving templates.
So, what’s the problem with that code?
The problem is that the std::max function template is declared something like this:
template <typename T> const T& max(const T& a, const T& b)
If you look at the initial code invoking std::max, the first argument is of type int; the second argument is of type double (i.e. the return type of f).
Now, if you look at the declaration of std::max, you’ll see that both parameters are expected to be of the same type T. So, the C++ compiler complains as it’s unable to deduce the type of T in the code calling std::max: should T be int or double?
This ambiguity triggers a compile-time error.
To fix this error, you can use the double literal 0.0 instead of 0.
And, what if instead of 0 there’s a variable of type int?
Well, in this case you can either static_cast that variable to double:
double x = std::max(static_cast<double>(n), f(/* something */));
or, as an alternative, you can explicitly specify the double template type for std::max:
double x = std::max<double>(n, f(/* something */));