Почему std:: stoul конвертирует отрицательные числа?

Как показано в http://ideone.com/RdINqa, std::stoul не выбрасывает std::out_of_range для отрицательных чисел, но обертывает их. Почему это? Кажется, что -4 находится вне диапазона типа unsigned long, поэтому он должен бросать.

Ответ 1

21,5 Числовые преобразования

unsigned long stoul(const string& str, size_t *idx = 0, int base = 10);

Эффекты:... call [s] strtoul(str.c_str(), ptr, base)... возвращает преобразованный результат, если он есть.

Выдает:... out_of_range, если преобразованное значение находится за пределами диапазона представляемых значений для возвращаемого типа.

"Преобразованное значение" здесь - значение, возвращаемое strtoul. Который, конечно, имеет тип unsigned long и поэтому не может находиться за пределами диапазона представляемых значений для возвращаемого типа stoul, который также является unsigned long.

Насколько я могу судить, только stoi может бросать out_of_range, потому что он возвращает int, но использует strtol, который возвращает long.

Кроме того, способ C указывает strtoul, требуется принять строку "-4" и вернуть значение, равное -(unsigned long)4. Почему это указано таким образом, я не знаю.