Какая разница между std:: to_string, boost:: to_string и boost:: lexical_cast <std::string>?
Какова цель boost::to_string
(найдена в boost/exception/to_string.hpp
) и как она отличается от boost::lexical_cast<std::string>
и std::to_string
?
Ответы
Ответ 1
std::to_string
, доступный с С++ 11, специально работает с основными числовыми типами. Он также имеет вариант std::to_wstring
.
Он предназначен для получения тех же результатов, что и sprintf
.
Вы можете выбрать эту форму, чтобы избежать зависимостей от внешних библиотек/заголовков.
Функция броска при неудаче boost::lexical_cast<std::string>
и ее двоюродный брат без метания boost::conversion::try_lexical_convert
работают с любым типом, который можно вставить в std::ostream
включая типы из других библиотек или ваш собственный код.
Для распространенных типов существуют оптимизированные специализации с общей формой, напоминающей:
template< typename OutType, typename InType >
OutType lexical_cast( const InType & input )
{
// Insert parameter to an iostream
std::stringstream temp_stream;
temp_stream << input;
// Extract output type from the same iostream
OutType output;
temp_stream >> output;
return output;
}
Вы можете выбрать эту форму для повышения гибкости типов ввода в универсальных функциях или для создания std::string
из типа, который, как вы знаете, не является фундаментальным числовым типом.
boost::to_string
не документировано напрямую и, по-видимому, предназначено в основном для внутреннего использования. Его функциональность ведет себя как lexical_cast<std::string>
, а не std::to_string
.
Ответ 2
Есть больше различий: boost :: lexical_cast работает немного по-другому при преобразовании double в строку. Пожалуйста, рассмотрите следующий код:
#include <limits>
#include <iostream>
#include "boost/lexical_cast.hpp"
int main()
{
double maxDouble = std::numeric_limits<double>::max();
std::string str(std::to_string(maxDouble));
std::cout << "std::to_string(" << maxDouble << ") == " << str << std::endl;
std::cout << "boost::lexical_cast<std::string>(" << maxDouble << ") == "
<< boost::lexical_cast<std::string>(maxDouble) << std::endl;
return 0;
}
Результаты
$ ./to_string
std::to_string(1.79769e+308) == 179769313486231570814527423731704356798070600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
boost::lexical_cast<std::string>(1.79769e+308) == 1.7976931348623157e+308
Как видите, в улучшенной версии используются экспоненциальные обозначения (1.7976931348623157e + 308), тогда как std :: to_string печатает каждую цифру и шесть десятичных знаков. Один может быть более полезным, чем другой для ваших целей. Лично я считаю версию буста более читабельной.