0 Abstract There is always a saying that to become a master, you must read more highly handwritten source code. Which codes are good materials? C ++ standard library source code? No, if you have read it, you will find that either a variety of expressions that are unique to implementation are confusing, or a horrible code style (such as an underline everywhere) is uncomfortable. The Boost library code is quite clear, reasonable comments, and naming conventions are definitely a good example for reading. At the same time, Boost has a wide range of content, such as numerical computing, generic programming, metaprogramming, and platform API ...... You may wish to carefully select what you are interested in.
In this article, we will introduce the download and installation of the Boost library, and will experience lexcial_cast, a very simple and practical component in the Boost library.
1 Boost Introduction What is Boost? A set of open source code and highly portable C ++ libraries.
Who initiated it? C ++ Standards Committee Database Working Group. Therefore, quality assurance is not afraid of counterfeit and shoddy products.
What about it? Look:
- Regular Expressions are comparable to posix api and Perl for processing regular expressions, and support various character types (such as char, wchar_t, it can even be a custom character type );
- Multithreading: I have been thinking about a multi-threaded cross-platform library for a long time;
- The data structure "Graph", coupled with the standard hash_set, hash_map, hash_multiset, and hash_multimap to be added (in fact, many STL implementations, such as sgi stl, already support the above data structures ), C ++'s support for data structures is nearly complete;
- Python. That's right. Support for Python;
- Smart pointers can be used together with std: auto_ptr to prevent memory leakage, making it more efficient than garbage collection mechanism GC;
- More Cyclic Redundancy CRC, tuple that can easily be defined to return multiple value functions, any that can hold different types of values, Supplement to the standard library ......
- Some content is expected to enter the C ++ standard library ......
2 Boost download and Boost Installation Where can I download Boost? English http://www.boost.org (1), Chinese http://boost.c-view.org, can find a. zipor .tar.gz format compressed package. After the download is complete, decompress the package to a directory, such as boost_000026_0, which generally contains the following subdirectories: boost, libs, more, people, status, and tools. Just check if there is no problem.
If you are too lazy to download the entire compressed package when the Boost is updated, you only want to update the file that has changed; or you are a Boost Fans like me, and want to track the latest Boost changes, use CVS. First, you must have a CVS client software, such as CvsGui or idea. Download, install, and start.
If you are used to the traditional Command Line mode of CVS, you can enter the following line 2 in Admin → Command Line... → Command line settings:
cvs -z3 -d:pserver:anonymous@cvs.boost.sourceforge.net:/cvsroot/boost checkout boost
Check the following check box, select the local target directory (for example, you can create a new C:/Boost, which depends on your hobbies), and click OK to start the update. If this is the first time, it may take some time to download all the files. Of course it will take a short time to update later.
If you prefer the GUI mode, select Admin → Preferences... and Enter the following in General's Enter cvs root:
anonymous@cvs.boost.sourceforge.net:/cvsroot/boost
Select "passwd" file on the cvs server for Authentication, and select cvs 1.10 (standard) for Use version ). In WinCvs's HOME folder, enter or select a local target directory and click OK. Select View → Browse Location → Change... after changing to the local target directory, go to Create → Check Module... → Enter the module name and path in the server of the Checkout Settings, Enter boost, and click OK. If you need to enter the password during this process, just press Enter. This is where WinCVS 1.2 is used. If you are downloading a new version, pay attention to the same settings. For example, if you select pserver for the previous Authentication, you do not need to set Use version.
Then set the compiler. Take Windows integrated environment as an example. Microsoft Visual C ++ 6.0, you can add the Boost path (for example, boost_000026_0 in front of the tool → select → directory) to the Include Files search path. For Borland C ++ Builder 5.0, the Boost Path is added to Project → Options → Directories/Conditionals → Include Path. There is also a more common Dev-C ++ 4.0 (built-in gnu c ++, which can be downloaded free of charge from the http://www.bloodshed.net ), you can add the Boost path in Options → Compile Options → Directories → C ++ include files. Similar to other ides. For the command line method, you need to specify the path parameters for the corresponding header file during compilation (Borland C ++ Compiler, gnu c ++ is-I, and VC ++'s cl Is/I) the Boost path is provided.
Congratulations, you can use most of the Boost libraries.
Why not all? First of all, there is no Compiler that fully complies with the C ++ standard, so the components in the Boost library are more or less unavailable. For details, see "Compiler support (Compiler Status)" on the Boost website). In addition, some libraries need to Build corresponding lib or dll files. However, there are few such libraries, mainly because of platform relevance, such as the regex library for processing Regular Expressions and python library that supports the python language. The process of constructing a library is cumbersome, you need to use the Jam tool (you can simply mention: In the tools/build/jam_src/builds directory there are three file win32-borlandc.mk, win32-gcc.mk, win32-visualc. mk is a mak file for Borland C ++ Compiler, gnu c ++, and Visual C ++ on Windows. If you are on a Unix platform, you should use tools/build/Makefile. Use the command line tool make or nmake to make the Jam execution file, and then use Jam to construct the library. For details, see the Boost. Build document ). My personal suggestion is that you do not need to rush to construct lib or dll. Make the mak file provided with the library when you really need to use these libraries. Although Boost. Jam may be the future direction of Boost libraries, most libraries do not need to be constructed and can be used directly.
3 Boost component lexical_cast This time, we will first pick a simple and practical Boost component to see how convenient Boost can bring us.
3.1 string → Value
On the CSDN forum, I often see questions about how to convert string and numeric types. I also see many different answers. Next we will first discuss the conversion from the string type to the numeric type.
- How to convert a string "123" to an integer of the int type 123? The answer is: use the standard C library function atoi;
- What if you want to convert it to the long type? Standard C library function atol;
- How to convert "123.12" to double type? Standard C library function atod;
- What if I want to convert it to the long double type? Standard C library function atold;
- ......
Later, a friend began to use the string class in the standard library and asked how to convert it to a value? A friend replied, Please convert it to const char * first *. I admire the mathematician's thinking of the Q & A: Turning unfamiliar questions into familiar questions. (Once there was a joke, so I asked mathematicians: Do you know how to boil water? A: Yes. Fill the water bottle with water and ignition. Q: What if there is already water in the kettle? A: Switch it down first and it turns into a problem that I am familiar ......)
No, no. This is the practice of C, not C ++. So what should C ++ do? Using the function lexical_cast provided by Boost Conversion Library (the header file boost/lexical_cast.hpp needs to be introduced) is undoubtedly the easiest and most convenient. For example:
#include <boost/lexical_cast.hpp>#include <iostream>int main(){ using boost::lexical_cast; int a = lexical_cast<int>("123"); double b = lexical_cast<double>("123.12"); std::cout<<a<<std::endl std::cout<<b<<std::endl; return 0;}
A function solves all the problems in a simple way.
3.2 value → string
So from the value type to the string type?
Using itoa? No, this function is not available in Standard C/C ++. Even if some compilers on the Windows platform provide this function 3 without any portability, the int type can only be solved (maybe other functions can also solve the long, unsigned long and other types ), what about the floating point type? Of course, there are still some solutions, that is: sprintf.
char s[100];sprintf(s, "%f", 123.123456);
I don't know how you think about the scanf/printf series in C. In short, I can't remember the odd parameters in a pair, and if the parameter is wrong, the output results will be uncertain, and debugging will be terrible (I hate character arrays more, the space is 100, and I am afraid it is too small to fit; the space is 100000, I always feel that it is a waste of resources, so I am so angry. Fortunately, the C ++ standard provides us with a string class like string ). At this time, lexical_cast will help you.
#include <boost/lexical_cast.hpp>#include <string>#include <iostream>int main(){ using std::string; const double d = 123.12; string s = boost::lexical_cast<string>(d); std::cout<<s<<std::endl; return 0;}
It is as simple as above.
3.3 exceptions
If the conversion fails, bad_lexical_cast will throw an exception. This exception class is a subclass of the standard exception class bad_cast.
#include <boost/lexical_cast.hpp>#include <iostream>int main(){ using std::cout; using std::endl; int i; try{ i = boost::lexical_cast<int>("abcd"); } catch(boost::bad_lexical_cast& e) { cout<<e.what()<<endl; return 1; } cout<<i<<endl; return 0;}
Obviously, "abcd" cannot be converted to an int value. Therefore, an exception is thrown, and information such as "bad lexical cast: source type value cocould not be interpreted as target" is output.
3.4 precautions
Lexical_cast depends on the upstream stream std: stringstream (header files are automatically introduced. 4), the principle is quite simple: Read the source type into the pipeline stream, and then write it to the target type. For example
int d = boost::lexical_cast<int>("123");
It is equivalent
int d;std::stringstream s;s<<"123";s>>d;
Since the ghost stream is used, of course, there are some problems that need to be pointed out in particular 5.
- Due to some problems with the locale implementation of Visual C ++ 6, if non-default locale is used, an exception may be thrown inexplicably. Of course, in general, we do not need to change the default locale, so the problem is not great.
- The input data must be completely converted; otherwise, a bad_lexical_cast exception is thrown. For example
int i = boost::lexical_cast<int>("123.123"); // this will throw
An exception is thrown. Because "123.123" can only be partially converted to 123, and cannot be fully converted to 123.123.
- The accuracy of floating point numbers.
std::string s = boost::lexical_cast<std::string>(123.1234567);
The expected result of the preceding statement is "123.1234567", but we only get "123.123", because std :: the precision of stringstream is 6 (this is the tradition left by the "Predecessors" printf in the C language library ). This is a bug in boost: lexical_cast. What should we do? You can do this by opening the header file. , Note that modify 6 as follows:
#include <boost/limits.hpp>//...template<typename Target, typename Source>Target lexical_cast(Source arg) { //... Target result; interpreter.precision(std::numeric_limits<Source>::digits10); if( !(interpreter << arg) || !(interpreter >> result) || !(interpreter >> std::ws).eof()) //...}
You can get the correct result. Of course, theoretically, the efficiency will suffer a little loss, but it is almost negligible.
4. Summary We have already experienced boost: lexcial_cast. Of course, lexical_cast is not limited to conversions between string and numeric types: It can be converted between types that can be output to stringstream or any types that can be input from stringstream. Although this understanding is rough, after all, we have "walked into Boost", not just "approaching ". In the future, we will be able to appreciate the benefits of Boost.
5. Notes
[1]If a DNS error occurs when you access the Boost English website, try http: // 64.226.201.52 /.
[2]See "Boost Download and Installation" in the Boost documentation.
[3]Borland C ++ Builder provides itoa, while Microsoft Visual C ++ provides a function with the same functions, but its name is _ itoa.
[4]In some standard library implementations that do not comply with the standards, the streaming class name is strstream, in the header file . The Standard specifies stringstream, in the header file .
[5]For more information, see http://groups.yahoo.com/group/boost/message/15023.
[6]We are very grateful to Andrew Koenig and Bjarne Stroustrup for their suggestions and help. At first, my idea was to specify the maximum precision and add statements such as interpreter. precision (15). However, I was worried about portability. Mr. Andrew Koenig gave a very clear explanation: You are quite correct that 15 is not portable internal SS all floating-point implementations. however, it is portable within SS all implementations that support IEEE floating-point arithmetic, which is most computers that are in common use today. if you want to do better than that, you might consider using numeric_limits : Digits10, which is the number of significant base-10 digits that can be accurately represented in a double. (It is true that 15 is not portable to all floating-point implementations, but it is indeed portable for implementations that support IEEE floating-point operations, this is also used by most computers today. If you want to do better, consider using numeric_limits : Digits10, which indicates the number of digits that can be accurately expressed in the decimal double .)