Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

template<class T> string to_string(const T& t)

{

ostringstream os;

os << t;

return os.str;

}

Рассмотрим пример.

string s1 = to_string(12.333);

string s2 = to_string(1+5*6–99/7);

Значение строки

s1
равно "
12.333
", а значение строки
s2
— "
17
". Фактически функцию
to_string
можно применять не только к числовым значениям, но и к любому классу
T
с оператором
<<
.

Обратное преобразование, из класса

string
в число, так же просто, как и полезно.

struct bad_from_string:std::bad_cast

// класс для сообщений об ошибках при преобразовании строк

{

const char* what const // override bad_cast’s what

{

return "bad cast from string";

}

};

template<class T> T from_string(const string& s)

{

istringstream is(s);

T t;

if (!(is >> t)) throw bad_from_string;

return t;

}

Рассмотрим пример.

double d = from_string<double>("12.333");

void do_something(const string& s)

try

{

int i = from_string<int>(s);

// ...

}

catch (bad_from_string e) {

error ("Неправильная строка ввода",s);

}

Дополнительная сложность функции

from_string
по сравнению с функцией
to_string
объясняется тем, что класс
string
может представлять значения многих типов. Это значит, что каждый раз мы должны указывать, какой тип значений хотим извлечь из объекта класса
string
. Кроме того, это значит, что класс
string
, который мы изучаем, может не хранить значение типа, который мы ожидаем. Рассмотрим пример.

int d = from_string<int>("Mary had a little lamb"); // Ой!

Итак, возможна ошибка, которую мы представили в виде исключения типа

bad_from_string
. В разделе 23.9 мы покажем, что функция
from_string
(или эквивалентная) играет важную роль в серьезных текстовых приложениях, поскольку нам необходимо извлекать числовые значения из текстовых полей. В разделе 16.4.3 было показано, как эквивалентная функция
get_int
используется в графическом пользовательском интерфейсе.

Обратите внимание на то, что функции

to_string
и
from_string
очень похожи. Фактически они являются обратными друг другу; иначе говоря (игнорируя детали, связанные с пробелами, округлением и т.д.), для каждого “разумного типа
T
” имеем

s==to_string(from_string<T>(s)) // для всех s

и

t==from_string<T>(to_string(t)) // для всех t

Здесь слово “разумный” означает, что тип

T
должен иметь конструктор по умолчанию, оператор
>>
и соответствующий оператор
<<
.

Следует подчеркнуть, что реализации функций
to_string
и
from_string
используют класс
stringstream
для выполнения всей работы. Это наблюдение было использовано для определения универсальной операции конвертирования двух произвольных типов с согласованными операциями
<<
и
>>
.

struct bad_lexical_cast:std::bad_cast

{

const char* what const { return "bad cast"; }

};

template<typename Target,typename Source>

Target lexical_cast(Source arg)

{

std::stringstream interpreter;

Target result;

if (!(interpreter << arg) // записываем arg в поток

|| !(interpreter >> result) // считываем result из потока

|| !(interpreter >> std::ws).eof) // поток пуст?

  • Читать дальше
  • 1
  • ...
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: