Анимация
JavaScript
|
Главная Библионтека
Несколько смущает тот факт, что настолько хорошая вещь оказалась вдруг нежелательной, но такова жизнь... Альтернатива №4: boost::lexicaLcast г) boost::1exical cast Если вы еще незнакомы с Boost [Boost], мой совет - познакомьтесь. Это открытая библиотека для С-ь + , написанная в основном членами комитета по стандартизации С++, которая представляет собой ие только пример хорошего кода, написаииого профессионалами в стиле стандартной библиотеки С+ + . Возможности этой библиотеки, по сути, претендуют на включение в очередной стандарт С+-, так что с ними стоит ознакомиться заранее. Кроме того, вы можете использовать се сейчас и совершенно бесплатно. Одна нз интересных возможностей, предусмотренных в Boost, ~- boost: :lexical cast, которая представляет собой оболочку вокруг stringstream. Boost включает также более мощные подходы, которые используют внутренние потоки и обеспечивают большое количество опций форматирования, в частности, boost: :format, но поскольку код, написанный Кэвлином Хенни (Kevlin Henncy), предельно краток и очень элегантен, я МОР) полностью представить его здесь (исключив обходные пути .оля старых компиляторов). И я делаю это, несмотря на то, что это - иеста1щарт11ая возможность. tempiate<typename Target, typename Source> Target 1exical cast( Source arg ) { std::stri ngstream interpreter; Target result; i f(!(i nterpreter « arg) !(i nterpreter » result) j !(i nterpreter >> std::ws).eot()) throw bad lexical cast(); return result; Заметим, что шаблон 1 exi cal„cast не предназначен для конкуренции с гораздо более мощным средством форматирования строк, таким как spri ntf. 1 exi cal cast предназначен для конвертирования данных из одного типа в другой, так что он может представить конкуренцию скорее для функций С типа atoi () и подобных. OflfraKo данный шаблон настолько близок рассматриваемой теме, что не упомянуть о нем просто невозможно. Ниже представлен пример 3-1 при использовании 1 exi cal„cast (требование вывода как минимум 4 си.мволов удалено). Пример 3-4: строковое представление данных в С++ с использованием boost::1exical cast. void PrettyFormatC int i, string& s ) { предельно просто: s = ]exical..cast<string>C i ) ; /. Простота использования и ясность. Не стоит и доказывать, что данный код проще и понятнее всех ранее рассмотренных вариантов. 2. Эффективность (возможность непосредственного использования существующих буферов). Поскольку lexical cast использует stringstream, не удивительно, что при работе он требует вьлдсления па.мяти, как минимум, в том же количестве, что и stri ngstream. На одной из опробованных мною платформ в примере 3-4 было выполнено на одно выделение памяти больше, чем требуется при использовании обычного stri ngstream (см. пример 3-2); на другой платформе дополнительного выделения памяти не было. В остальных аспектах - безопасности и возможности использования в шаблонах 1exical „cast соответствует stringstream. Результаты сравнения lexical cast и spri ntf представлены в следующей таблице.
Резюме Конечно, ряд вопросов не бьгл рассмотрен нами подробно. Например, все форматирование строк рассматривалось нами только в отношении обычных символов, а во-ггросы использования "широких" символов нами не затрагивались. Кроме того, вопросы эффективности затрагивались нами в плане непосредственного использования существующих буферов, но другая сторона этой эффективности - необходимость угфавления памятью программистом при использовании sprintf, snprintf и strstream, в то время как применение stri ngstream, strstream и 1 exi cal cast позволяет вам избежать этого. (Здесь нет опечатки или противоречия, strstream внесен в оба списка в связи с тем, что его можно использовать и так, и этак,) Помимо 1 exi calcast, рассмотренного здесь в силу его краткости и элегантности, имеется масса других нестандартных альтернатив функции sprintf, в том числе в самой библиотеке Boost (например, такая замечательная и очень мошная вещь, как boost: : format, позволяющая добавить форматирование в стиле spri ntf к уже рассмотренным stri ngstream и strstream), Лосле обобщения результатов исследований мы получили сводную табл, 3,1, из которой понятно, что идеального варианта не существует, но, тем не Metiee, можно дать определенные рекомендации, которые сведенЬ1 в табл, 3,2, » Если необходимо преобразовать значение в строку stri ng (или во что-то иное) - используйте boost: : 1 exical cast. Для простого форматирования, или при необходимости поддержки широких строк, или для использования в шаблонах выбирайте stringstream или strstream. Для выполнения более сложного форматирования, если не требуется поддержка широких строк или использование в шаблонах, воспользуйтесь функцией snpri ntf. То, что это функция из С, вовсе не означает, что она не может быть использованной в С++! Если проведенные измерения показывают, что проблема производительности действительно связана с использованием неэффективного метода форматирования, только в этом случае, только в этих конкретных местах кода имеет смысл воспользоваться одной из более быстрых альтернатив -- strstream или snprintf. Никогда не используйте spri ntf. Таблица 3.1. Сравнение различных методов форматирования строк
0 1 2 3 4 5 6 [ 7 ] 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |