| 1 | <!-- saved from url=(0022)http://internet.e-mail --> |
|---|
| 2 | <!doctype html public "-//W3C//DTD HTML Transitional 4.0//EN"> |
|---|
| 3 | <html> |
|---|
| 4 | <head> |
|---|
| 5 | <title>lexical_cast</title> |
|---|
| 6 | <meta name="author" content="Kevlin Henney, mailto:kevlin@curbralan.com"> |
|---|
| 7 | <meta name="generator" content="Microsoft FrontPage 4.0"> |
|---|
| 8 | </head> |
|---|
| 9 | <body bgcolor="#FFFFFF" text="#000000"> |
|---|
| 10 | <h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" width="277" height="86">Header |
|---|
| 11 | <a href="../../boost/lexical_cast.hpp">boost/lexical_cast.hpp</a></h1> |
|---|
| 12 | <ul type="square"> |
|---|
| 13 | <li> |
|---|
| 14 | <a href="#motivation">Motivation</a></li> |
|---|
| 15 | <li> |
|---|
| 16 | <a href="#examples">Examples</a></li> |
|---|
| 17 | <li> |
|---|
| 18 | <a href="#synopsis">Synopsis</a></li> |
|---|
| 19 | <li> |
|---|
| 20 | <a href="#lexical_cast"><code>lexical_cast</code></a></li> |
|---|
| 21 | <li> |
|---|
| 22 | <a href="#bad_lexical_cast"><code>bad_lexical_cast</code></a></li> |
|---|
| 23 | <li> |
|---|
| 24 | <a href="#changes">Changes</a></li> |
|---|
| 25 | </ul> |
|---|
| 26 | <hr> |
|---|
| 27 | <h2><a name="motivation">Motivation</a></h2> |
|---|
| 28 | Sometimes a value must be converted to a literal text form, such as an <code>int</code> |
|---|
| 29 | represented as a <code>string</code>, or vice-versa, when a <code>string</code> |
|---|
| 30 | is interpreted as an <code>int</code>. Such examples are common when converting |
|---|
| 31 | between data types internal to a program and representation external to a |
|---|
| 32 | program, such as windows and configuration files. |
|---|
| 33 | <p> |
|---|
| 34 | The standard C and C++ libraries offer a number of facilities for performing |
|---|
| 35 | such conversions. However, they vary with their ease of use, extensibility, and |
|---|
| 36 | safety. |
|---|
| 37 | <p> |
|---|
| 38 | For instance, there are a number of limitations with the family of standard C |
|---|
| 39 | functions typified by <code>atoi</code>: |
|---|
| 40 | <ul type="square"> |
|---|
| 41 | <li> |
|---|
| 42 | Conversion is supported in one direction only: from text to internal data type. |
|---|
| 43 | Converting the other way using the C library requires either the inconvenience |
|---|
| 44 | and compromised safety of the <code>sprintf</code> function, or the loss of |
|---|
| 45 | portability associated with non-standard functions such as <code>itoa</code>. |
|---|
| 46 | </li> |
|---|
| 47 | <li> |
|---|
| 48 | The range of types supported is only a subset of the built-in numeric types, |
|---|
| 49 | namely <code>int</code>, <code>long</code>, and <code>double</code>. |
|---|
| 50 | </li> |
|---|
| 51 | <li> |
|---|
| 52 | The range of types cannot be extended in a uniform manner. For instance, |
|---|
| 53 | conversion from string representation to <code>complex</code> or <code>rational</code>. |
|---|
| 54 | </li> |
|---|
| 55 | </ul> |
|---|
| 56 | The standard C functions typified by <code>strtol</code> have the same basic |
|---|
| 57 | limitations, but offer finer control over the conversion process. However, for |
|---|
| 58 | the common case such control is often either not required or not used. The <code>scanf</code> |
|---|
| 59 | family of functions offer even greater control, but also lack safety and ease |
|---|
| 60 | of use. |
|---|
| 61 | <p> |
|---|
| 62 | The standard C++ library offers <code>stringstream</code> for the kind of |
|---|
| 63 | in-core formatting being discussed. It offers a great deal of control over the |
|---|
| 64 | formatting and conversion of I/O to and from arbitrary types through text. |
|---|
| 65 | However, for simple conversions direct use of <code>stringstream</code> can be |
|---|
| 66 | either clumsy (with the introduction of extra local variables and the loss of |
|---|
| 67 | infix-expression convenience) or obscure (where <code>stringstream</code> |
|---|
| 68 | objects are created as temporary objects in an expression). Facets provide a |
|---|
| 69 | comprehensive concept and facility for controlling textual representation, but |
|---|
| 70 | their perceived complexity and high entry level requires an extreme degree of |
|---|
| 71 | involvement for simple conversions, and excludes all but a few programmers. |
|---|
| 72 | <p> |
|---|
| 73 | The <code>lexical_cast</code> function template offers a convenient and |
|---|
| 74 | consistent form for supporting common conversions to and from arbitrary types |
|---|
| 75 | when they are represented as text. The simplification it offers is in |
|---|
| 76 | expression-level convenience for such conversions. For more involved |
|---|
| 77 | conversions, such as where precision or formatting need tighter control than is |
|---|
| 78 | offered by the default behavior of <code>lexical_cast</code>, the conventional <code> |
|---|
| 79 | stringstream</code> approach is recommended. Where the conversions are |
|---|
| 80 | numeric to numeric, <code><a href="../numeric/conversion/doc/numeric_cast.html">numeric_cast</a></code> |
|---|
| 81 | may offer more reasonable behavior than <code>lexical_cast</code>. |
|---|
| 82 | <p> |
|---|
| 83 | For a good discussion of the options and issues involved in string-based |
|---|
| 84 | formatting, including comparison of <code>stringstream</code>, <code>lexical_cast</code>, |
|---|
| 85 | and others, see Herb Sutter's article, <a href="http://www.gotw.ca/publications/mill19.htm"> |
|---|
| 86 | <i>The String Formatters of Manor Farm</i></a>. |
|---|
| 87 | <p> |
|---|
| 88 | <hr> |
|---|
| 89 | <h2><a name="examples">Examples</a></h2> |
|---|
| 90 | The following example treats command line arguments as a sequence of numeric |
|---|
| 91 | data: <blockquote> |
|---|
| 92 | <pre> |
|---|
| 93 | int main(int argc, char * argv[]) |
|---|
| 94 | { |
|---|
| 95 | using boost::lexical_cast; |
|---|
| 96 | using boost::bad_lexical_cast; |
|---|
| 97 | |
|---|
| 98 | std::vector<short> args; |
|---|
| 99 | |
|---|
| 100 | while(*++argv) |
|---|
| 101 | { |
|---|
| 102 | try |
|---|
| 103 | { |
|---|
| 104 | args.push_back(lexical_cast<short>(*argv)); |
|---|
| 105 | } |
|---|
| 106 | catch(bad_lexical_cast &) |
|---|
| 107 | { |
|---|
| 108 | args.push_back(0); |
|---|
| 109 | } |
|---|
| 110 | } |
|---|
| 111 | ... |
|---|
| 112 | } |
|---|
| 113 | </pre> |
|---|
| 114 | </blockquote>The following example uses numeric data in a string expression: <blockquote> |
|---|
| 115 | <pre> |
|---|
| 116 | void log_message(const std::string &); |
|---|
| 117 | |
|---|
| 118 | void log_errno(int yoko) |
|---|
| 119 | { |
|---|
| 120 | log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko)); |
|---|
| 121 | } |
|---|
| 122 | </pre> |
|---|
| 123 | </blockquote> |
|---|
| 124 | <hr> |
|---|
| 125 | <h2><a name="synopsis">Synopsis</a></h2> |
|---|
| 126 | Library features defined in <a href="../../boost/lexical_cast.hpp"><code>"boost/lexical_cast.hpp"</code></a>: |
|---|
| 127 | <blockquote> |
|---|
| 128 | <pre> |
|---|
| 129 | namespace boost |
|---|
| 130 | { |
|---|
| 131 | class <a href="#bad_lexical_cast">bad_lexical_cast</a>; |
|---|
| 132 | template<typename Target, typename Source> |
|---|
| 133 | Target <a href="#lexical_cast">lexical_cast</a>(Source arg); |
|---|
| 134 | } |
|---|
| 135 | </pre> |
|---|
| 136 | </blockquote>Unit test defined in <a href="lexical_cast_test.cpp"><code>"lexical_cast_test.cpp"</code></a>. |
|---|
| 137 | <p> |
|---|
| 138 | <hr> |
|---|
| 139 | <h2><a name="lexical_cast"><code>lexical_cast</code></a></h2> |
|---|
| 140 | <blockquote> |
|---|
| 141 | <pre> |
|---|
| 142 | template<typename Target, typename Source> |
|---|
| 143 | Target lexical_cast(Source arg); |
|---|
| 144 | </pre> |
|---|
| 145 | </blockquote>Returns the result of streaming <code>arg</code> into a |
|---|
| 146 | standard library string-based stream and then out as a <code>Target</code> object. |
|---|
| 147 | Where <code>Target</code> is either <code>std::string</code> |
|---|
| 148 | or <code>std::wstring</code>, stream extraction takes the whole content |
|---|
| 149 | of the string, including spaces, rather than relying on the default |
|---|
| 150 | <code>operator>></code> behavior. |
|---|
| 151 | If the conversion is unsuccessful, a <a href="#bad_lexical_cast"> |
|---|
| 152 | <code>bad_lexical_cast</code></a> exception is thrown. |
|---|
| 153 | <p> |
|---|
| 154 | The requirements on the argument and result types are: |
|---|
| 155 | <ul type="square"> |
|---|
| 156 | <li> |
|---|
| 157 | <code>Source</code> is <i>OutputStreamable</i>, meaning that an <code>operator<<</code> |
|---|
| 158 | is defined that takes a <code>std::ostream</code> or <code>std::wostream</code> object on the |
|---|
| 159 | left hand side and an instance of the argument type on the right. |
|---|
| 160 | </li> |
|---|
| 161 | <li> |
|---|
| 162 | <code>Target</code> is <i>InputStreamable</i>, meaning that an <code>operator>></code> |
|---|
| 163 | is defined that takes a <code>std::istream</code> or <code>std::wistream</code> object on the left hand side |
|---|
| 164 | and an instance of the result type on the right. |
|---|
| 165 | </li> |
|---|
| 166 | <li> |
|---|
| 167 | Both <code>Source</code> and <code>Target</code> are <i>CopyConstructible</i> [20.1.3]. |
|---|
| 168 | </li> |
|---|
| 169 | <li> |
|---|
| 170 | <code>Target</code> is <i>DefaultConstructible</i>, meaning that it is possible |
|---|
| 171 | to <i>default-initialize</i> an object of that type [8.5, 20.1.4]. |
|---|
| 172 | </li> |
|---|
| 173 | </ul> |
|---|
| 174 | The character type of the underlying stream is assumed to be <code>char</code> unless |
|---|
| 175 | either the <code>Source</code> or the <code>Target</code> requires wide-character |
|---|
| 176 | streaming, in which case the underlying stream uses <code>wchar_t</code>. |
|---|
| 177 | <code>Source</code> types that require wide-character streaming are <code>wchar_t</code>, |
|---|
| 178 | <code>wchar_t *</code>, and <code>std::wstring</code>. <code>Target</code> types that |
|---|
| 179 | require wide-character streaming are <code>wchar_t</code> and <code>std::wstring</code>. |
|---|
| 180 | <p> |
|---|
| 181 | Where a higher degree of control is required over conversions, <code>std::stringstream</code> |
|---|
| 182 | and <code>std::wstringstream</code> offer a more appropriate path. Where non-stream-based conversions are |
|---|
| 183 | required, <code>lexical_cast</code> |
|---|
| 184 | is the wrong tool for the job and is not special-cased for such scenarios. |
|---|
| 185 | <p> |
|---|
| 186 | <hr> |
|---|
| 187 | <h2><a name="bad_lexical_cast"><code>bad_lexical_cast</code></a></h2> |
|---|
| 188 | <blockquote> |
|---|
| 189 | <pre> |
|---|
| 190 | class bad_lexical_cast : public std::bad_cast |
|---|
| 191 | { |
|---|
| 192 | public: |
|---|
| 193 | ... // <i>same member function interface as</i> std::exception |
|---|
| 194 | }; |
|---|
| 195 | </pre> |
|---|
| 196 | </blockquote>Exception used to indicate runtime <a href="#lexical_cast"><code>lexical_cast</code></a> |
|---|
| 197 | failure. |
|---|
| 198 | <hr> |
|---|
| 199 | |
|---|
| 200 | <h2><a name="changes">Changes</a></h2> |
|---|
| 201 | <h3>June 2005:</h3> |
|---|
| 202 | <ul type="square"> |
|---|
| 203 | <li>Call-by-const reference for the parameters. This requires partial specialization |
|---|
| 204 | of class templates, so it doesn't work for MSVC 6, and it uses the original |
|---|
| 205 | pass by value there.<br> |
|---|
| 206 | </li> |
|---|
| 207 | <li>The MSVC 6 support is deprecated, and will be removed in a future Boost |
|---|
| 208 | version. </li> |
|---|
| 209 | </ul> |
|---|
| 210 | <h3>Earlier:</h3> |
|---|
| 211 | |
|---|
| 212 | <ul type="square"> |
|---|
| 213 | <li>The previous version of <code>lexical_cast</code> used the default stream |
|---|
| 214 | precision for reading and writing floating-point numbers. For numerics that |
|---|
| 215 | have a corresponding specialization of <code>std::numeric_limits</code>, the |
|---|
| 216 | current version now chooses a precision to match. <br> |
|---|
| 217 | <li>The previous version of <code>lexical_cast</code> did not support conversion |
|---|
| 218 | to or from any wide-character-based types. For compilers with full language |
|---|
| 219 | and library support for wide characters, <code>lexical_cast</code> now supports |
|---|
| 220 | conversions from <code>wchar_t</code>, <code>wchar_t *</code>, and <code>std::wstring</code> |
|---|
| 221 | and to <code>wchar_t</code> and <code>std::wstring</code>. <br> |
|---|
| 222 | <li>The previous version of <code>lexical_cast</code> assumed that the conventional |
|---|
| 223 | stream extractor operators were sufficient for reading values. However, string |
|---|
| 224 | I/O is asymmetric, with the result that spaces play the role of I/O separators |
|---|
| 225 | rather than string content. The current version fixes this error for <code>std::string</code> |
|---|
| 226 | and, where supported, <code>std::wstring</code>: <code>lexical_cast<std::string>("Hello, |
|---|
| 227 | World")</code> succeeds instead of failing with a <code>bad_lexical_cast</code> |
|---|
| 228 | exception. <br> |
|---|
| 229 | <li>The previous version of <code>lexical_cast</code> allowed unsafe and meaningless |
|---|
| 230 | conversions to pointers. The current version now throws a <code>bad_lexical_cast</code> |
|---|
| 231 | for conversions to pointers: <code>lexical_cast<char *>("Goodbye, World")</code> |
|---|
| 232 | now throws an exception instead of causing undefined behavior. |
|---|
| 233 | </ul> |
|---|
| 234 | <p> |
|---|
| 235 | <hr> |
|---|
| 236 | |
|---|
| 237 | <div align="right"><small><i>© Copyright Kevlin Henney, 2000–2005</i></small></div> |
|---|
| 238 | </body> |
|---|
| 239 | </html> |
|---|