Подтвердить что ты не робот

Почему строка `std:: sto`... не является шаблоном?

Интересно, есть ли причина, по которой серия std::sto (например, std::stoi, std::stol) не является шаблоном функции, например:

template<typename T>
T sto(std::string const & str, std::size_t *pos = 0, int base = 10);

а затем:

template<>
int sto<int>(std::string const & str, std::size_t *pos, int base)
{
    // do the stuff.
}

template<>
long sto<long>(std::string const & str, std::size_t *pos, int base)
{
    // do the stuff.
}

/* etc. */

В моем смысле, это будет лучший дизайн, потому что на данный момент, когда мне нужно преобразовать строку в любое числовое значение, которое требуется пользователю, я должен вручную управлять каждым случаем.

Есть ли причина не иметь такую ​​функцию шаблона? Есть ли предполагаемый выбор, или это просто так?

4b9b3361

Ответ 1

I have to manage manually each case. Is there a reason to not have such a template function?

В случае таких вопросов Эрик Липперт (С#) обычно говорит что-то в строках:

Если функция отсутствует, она отсутствует, поскольку ее еще не реализовано. И это потому, что либо еще никто раньше не хотел, или потому, что считалось нецелесообразным, либо потому, что он не мог быть закончен, прежде чем публиковать текущую версию ".

Здесь, я думаю, это "не стоит", но я не спрашивал об этом коммите и не нашел ответа в старых вопросах и вопросах. Я не тратил много времени на поиск.

Я говорю это, потому что я полагаю, что наиболее распространенная функциональность этих функций (если не все) уже содержится в классах потоков, например istringstream. Точно так же, как cin/и т.д., Он также имеет all-have operator >>, перегруженный для всех базовых числовых типов (и более).

Кроме того, манипуляторы потока, такие как std::hex (std:: setbase), уже решают проблему передачи различных параметров конфигурации, зависящих от типа, к фактическим функциям преобразования. Нет проблем со смешанными сигнатурами функций (как, например, Дэвидом Хаим в его ответе). Вот только один operator>>.

Итак, поскольку, если мы имеем это в streams, если мы уже можем читать числа /etc из строк с помощью простого foo >> bar >> setbase(42) >> baz >> ..., то я думаю, что не стоит пытаться добавлять более сложные слои к старой среде выполнения C функции.

Нет доказательств для этого. Просто догадка.

Ответ 2

Глядя на описание этих функций в cppref, я отмечаю следующее:

... Интерпретирует знаковое целочисленное значение в строке str.

1) вызывает std::strtol(str.c_str(), &ptr, base)...

и strol стандартная функция "C", которая также доступна на С++.

Далее, мы видим: (для функций С++ sto*):

Возвращаемое значение

Строка, преобразованная в указанный целочисленный тип со знаком.

Исключения

  • std::invalid_argument, если преобразование не может быть выполнено
  • std::out_of_range, если преобразованное значение выпадет из диапазона типа результата или если основная функция (std:: strtol или std:: strtoll) устанавливает errno в ERANGE.

Поэтому, хотя у меня нет оригинального источника для этого и, действительно, никогда не работал с этими функциями, я бы предположил, что:

TL; DR: эти функции являются обертками С++ - ish вокруг уже существующих функций C/С++ - strtol* - так они напоминают эти функции как можно ближе.

Ответ 3

Проблема специализации шаблонов заключается в том, что специализация требует, чтобы вы соответствовали оригинальной сигнатуре функции шаблона, поэтому каждая специализация должна реализовывать интерфейс (string,pos,base).

Если вы хотите иметь какой-то другой тип, который не следует этому интерфейсу, у вас проблемы.

Предположим, что в будущем мы хотели бы иметь sto<std::pair<int,int>>. Мы хотим иметь pos и base для первого и второго строкового целого числа. мы хотим, чтобы подпись была в форме string,pos1,base1,pos2,base2. Поскольку sto подпись уже установлена, мы не можем этого сделать.

Вы всегда можете заключить std::sto* в свою реализацию sto для целых типов, но вы не можете сделать это наоборот.

Ответ 4

Цель этих функций - обеспечить простые преобразования для обычных случаев. Они не предназначены для конверсии общего назначения. std::ostringstream намного лучше для такого рода вещей.

Ответ 5

В моем смысле, был бы лучший дизайн, потому что на данный момент, когда мне нужно преобразовать строку в любое числовое значение пользователя хочу, я должен вручную управлять каждым случаем.

Нет, не будет. Цель шаблонов (намеренная установка T-MP отдельно) не, чтобы заменить перегрузку; вы всегда должны перегружать шаблоны. Собственно, это то, что язык уже делает для вас! Между кандидатской функцией и возможной возможностью создания шаблона будет предпочтительнее первая. Использование языковых функций для этого плохо.

Я не вижу, как могут помочь шаблоны. Независимо от типа, который пользователь решает ввести, он не будет известен до времени исполнения, а типы шаблонов выводятся во время компиляции. С++ - это статически типизированный язык. В этом случае шаблоны просто добавят ненужный уровень сложности при нормальной перегрузке функций.