Why are they "ints" ? One of the first things we realise, in both C++ and Rust, is that we mostly don't want these primitives like "int", we want our own user defined types, and Rust is better at that
in practice.
In the C and C++ people tend to actually write the file descriptor will be an int, and the timeout will be an int, and the user account number will be an int, and the error code will be an int... because the language doesn't help much when you don't want that.
In the Rust people actually write the file descriptor will be an OwnedFd (from the stdlib) and the timeout will be a Duration (from the stdlib), and user account number might be their own AcctNo and that error code is maybe MyCustomError
This is a language ethos thing, C++ got string slices after Rust despite the language being much older. String slices which are a really basic central idea, but eh, C++ programmers a decade ago just had char * pointers instead and tried not to think about it too much. Still today plenty of C++ APIs don't use string slices, don't work with a real duration type, and so on. It's technically possible but the language doesn't encourage this.
What C++ does encourage is magic implicit conversion, as with this f64 versus i64 case.