Какая разница между 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 печатает каждую цифру и шесть десятичных знаков. Один может быть более полезным, чем другой для ваших целей. Лично я считаю версию буста более читабельной.