If I have a function like void func(size_t x)
and I call the function func(5)
, is 5 immediately converted to size_t
type? Does this hold generally for all types?
I ask because I swear I've seen people write code where they do stuff like func(5.0)
(passing 5 as a double) or func(0UL)
(passing 0 as an unsigned long int). Is this really necessary? Can't we just pass in whatever we want, and C++ will treat it as the type that I used to define the function?
If there is an implicit conversion between the argument type and the type passed to the function then the argument will be converted. If there isn't one, like trying to pass a std::list
to a function that expects a std::vector
then it won't and you will get an error.
One reason to use a specific literal, like func(5.0)
or func(5UL)
is if func
is a template function, or is overloaded. If func
is a template or is overloaded (for the appropriate types) then func(5.0)
, func(5UL)
and func(5)
would generate/call 3 different functions. One for a double
, one for a unsigned long
and one for an int
. This could be meaningful as there could be specializations/overloads handling these types differently.
You also run into cases like std::accumulate
whose third parameter, the accumulator, has its own template type. Lets say you want to sum all of the elements in a std::vector<double>
. If you use
std::accumulate(vector.begin(), vector.end(), 0)
then you would get a different result than
std::accumulate(vector.begin(), vector.end(), 0.0)
because the first call uses an int
to store the sum which will truncate each time, while the latter uses a double
and you will get the expected result.