In C #, I would throw an ArgumentOutOfRange exception, but what should I do in C ++?
You should first consider whether this should be a prerequisite for your function, leaving it to the test to determine if the value is in the range of the caller.
If you decide this option, then calling the function with an out-of-range value will be undefined, and inside the function you can just have a debug statement to help you identify possible abuses - without having to throw any exception.
If you decide that the function should have a broad contract, on the other hand, and respond in a clearly defined way, throwing an exception if the argument is outside the valid range, you can throw a std::out_of_range exception.
For example: I write libary [...]
If you are writing a library, which means that you do not know the exact requirements of your customers in terms of performance and reliability, you can consider providing two such functions: one with a wide contract that generates exceptions, and one with a narrow contract that assumes that the client provides a meaningful contribution.
Thus, the user of your library could decide, based on his use cases, whether it is correct to pay the overhead of checking the correctness of input with each function call.
This is, for example, the strategy adopted by the standard C ++ library for std::vector , which provides non-casting of operator[] with a narrow contract for accessing collection items based on the index (this function has undefined behavior if the index is out of bounds), and the member function at() , which performs an index check and throws an exception if the index is out of bounds.