В стандартной библиотеке C ++ есть функции для преобразования из строковых в числовые типы:
stoi
stol
stoll
stoul
stoull
stof
stod
stold
но я считаю утомительным использовать их в шаблоне кода. Почему нет шаблонных функций что-то вроде:
template<typename T>
T sto(...)
преобразовать строки в числовые типы?
Я не вижу никаких технических причин, чтобы не иметь их, но, возможно, я что-то упустил. Они могут быть специализированными для вызова базовых именованных функций и использования enable_if
/ concepts
для отключения нечисловых типов.
Есть ли в стандартной библиотеке дружественные к шаблону альтернативы для преобразования строки в числовые типы и наоборот эффективным способом?
c++
string-conversion
Мирча Испас
источник
источник
Ответы:
C ++ 17 имеет такую обобщенную строку для числовой функции, но называется по-другому. Они пошли с
std::from_chars
, который перегружен для всех числовых типов.Как видите, первая перегрузка принимает любой целочисленный тип в качестве выходного параметра и присваивает ему значение, если это возможно.
Это можно использовать так:
Как видите, он может работать в общем контексте.
источник
Это не шаблон, и он не работает с локалями, но если это не ограничитель показа, то C ++ 17 уже имеет то, что вы хотите:
std::from_chars
Существуют перегрузки для всех целочисленных типов и типов с плавающей запятой, и интерфейс один и тот же, за исключением последних параметров, которые отличаются для целочисленных типов и типов с плавающей запятой соответственно (но если по умолчанию все в порядке, то вам не нужно изменить что угодно). Поскольку эта функция не поддерживает локали, она также довольно быстрая. Он превзойдет любую другую строку в функцию преобразования значений и, как правило, на порядки.
Существует очень хорошее видео CPPCON
<charconv>
(в которомfrom_chars
живет заголовок ) Стефана Т. Лававея, о его использовании и производительности можно посмотреть здесь: https://www.youtube.com/watch?v=4P_kbF0EbZMисточник
stoi
и его друзья (преобразования, упомянутые в вопросе) также не работают с локалями, так что это не шоу-стоппер.Вы не получите много, потому что в выражении, как
Не существует (простого) способа определить требуемый тип для параметра шаблона. Вы должны написать
что в некоторой степени противоречит цели предоставления универсальной функции. С другой стороны,
было бы полезно, как вы поняли. В C ++ 17 есть
std::from_chars
, что делает более-менее точно (это не шаблон, а набор перегрузок, и он использует указатели на символы вместо строки, но это лишь незначительные детали).PS Нет простого способа вывести нужный тип в приведенном выше выражении, но есть способ. Я не думаю, что в основе вашего вопроса была именно та подпись, о которой вы просили, и я не думаю, что следующее является хорошим способом для ее реализации, но я знал, что есть способ сделать вышеупомянутую
int x = sto("1");
компиляцию, и мне было любопытно увидеть ее в действии.Это работает как задумано, но имеет серьезные недостатки, возможно, самое главное, что оно позволяет писать
auto x = sto(s);
, то есть его легко использовать неправильно.источник
auto x = sto(s)
? Эта конкретная реализация ломается, потому чтоconverter::x
это ссылка, которая выходит за рамки, но это поправимо. Просто удалите ссылку и положитесь наstd::string
семантику перемещения.converter
, и я не уверен, что использование оператора преобразования шаблонов было лучшим выбором, вещи, которые можно исправить. Возможно это не так плохо, как я первоначально думалРешение, совместимое со всеми (даже более старыми компиляторами C ++, такими как C ++ - 98), заключается в использовании boost :: lexical_cast, который является шаблоном для преобразования между числовым и строковым типами обоими способами.
Пример:
См .: https://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm.
источник
В старых версиях C ++ stringstream - ваш друг. Если я правильно понимаю, то вам может быть интересно следующее. Это C ++ 11.
https://wandbox.org/permlink/nUNiUwWWTr7a0NXM
Этот метод работает в C ++ 11 и является довольно общим. По моему опыту, этот метод является надежным, но не самым эффективным.
источник