페이지

글타래

2009년 6월 11일 목요일

Visual Studio Technical Articles:: Boost for Visual C++ Developers

Visual Studio Technical Articles
Boost for Visual C++ Developers

Beman DawesFounder: Boost.org
May 2004
Summary: Discusses the C++ libraries developed by the Boost community, which add functionality beyond that currently included in the C++ Standard Library. Offers tips to developers for effectively using the Boost libraries, as well as how to contribute to Boost. (11 printed pages)
Contents
IntroductionWhat Is Boost?Boost and the C++ Standard LibraryTypical Boost LibrariesSmart PointersRegular ExpressionsOther Interesting Boost LibrariesUsing Boost with Visual C++Tips for Getting the Most Out of Boost LibrariesContributing to BoostConclusionRelated BooksAppendix: The C++ Standard Library Technical Report (TR)
Introduction
It's no secret that powerful libraries pump up C++ programmer productivity by providing ready-made solutions to common programming problems. Use of modern C++ libraries can shorten development cycles and improve the quality of the finished product.
The Boost community developed C++ libraries to add functionality that starts where the current C++ Standard Library leaves off. The Boost libraries are well known for their usefulness, and several have been accepted by the C++ standards committee for eventual ISO standardization.
The much improved C++ language compliance of Microsoft® Visual C++® .NET 2003 now supports full use of the Boost libraries. This article introduces Boost to Visual C++ developers and looks at some of the individual Boost libraries. It discusses Visual C++ IDE set up for Boost, and gives tips for effective use of the Boost libraries. Finally, the article looks at how you can contribute to Boost.
What Is Boost?
Boost is a Web site (www.boost.org) that provides "free peer-reviewed portable C++ source libraries." Boost isn't one library, but a collection of over 50 libraries that work well together. Library interdependencies are limited to cases where a dependency is justified by the value added. Many users start with only one or two Boost libraries, and then expand use over time.
All of Boost, including code, documentation, and everything else on the Web site is free. Free both in the sense of no charge for use of the libraries, and in the sense of no burdensome licenses, even for commercial use. To be accepted by Boost, libraries go through a formal public review. This peer-review process has resulted in very high-quality libraries. The code is portable, to allow use on multiple compilers and operating systems. Regression tests are run daily on more than a dozen compiler and operating system combinations. Source code is distributed for all libraries, so users can inspect, audit, and modify the code to suit local needs.
Boost can also be viewed as an open-source community. Over a hundred volunteer developers work directly on the libraries. Several thousand programmers worldwide participate in mailing lists, newsgroups, formal library reviews, testing, and all the other activities that support the Boost libraries. Commercial support is also available. There are Japanese language and Chinese language Boost mirror sites run by local Boosters in those countries. Universities and corporations, including Microsoft, help out in various ways, such as hosting mailing lists or contributing compilers.
Boost and the C++ Standard Library
The Boost libraries work well with the C++ Standard Library, and about a dozen of them have been accepted for the upcoming Standard Library Technical Report. That means these libraries will eventually be shipped with most C++ compilers. It's too early to say if or when Microsoft might ship the Technical Report libraries, but the Visual C++ team has been very supportive of Boost and the Library Technical Report, and is actively participating in both efforts. The Boost versions of these libraries are available today, and work very nicely with Visual C++ .NET 2003.
Typical Boost Libraries
We'll look at two Boost libraries that are useful in everyday programming: Smart Pointers and Regular Expressions. Both have been accepted for the Library Technical Report.
We'll also take a brief look at the Type Traits and Template Metaprogramming libraries. These infrastructure tools are especially useful for programmers who develop their own libraries.
Smart Pointers
Memory management in C++ is left up to the programmer. That's great in that it allows critical memory management decisions to be tailored to the application. On the other hand, careless use of heap memory can result in memory leaks and program crashes. Smart pointers are the preferred way in C++ to ensure correct management of dynamic memory allocated by new expressions. Smart pointers are similar to regular pointers, but take care of the details of deleting the object being pointed to when it is no longer needed. The C++ Standard Library already contains std::auto_ptr, a smart pointer with transfer-of-ownership semantics. Boost adds additional smart pointers to handle other common needs, such as shared-ownership semantics.
The Boost shared_ptr class template supplies a shared-ownership smart pointer that can manage dynamically allocated memory in a wide variety of applications, and can be used to intercommunicate with third-party libraries. Unlike std::auto_ptr, shared_ptr works fine with STL containers.
For example, to set up a std::vector of shared_ptr's to a type named Foo, code something like this:
Copy Code
typedef boost::shared_ptr FooPtr;
std::vector foo_vector;
The vector can then be populated like this:
Copy Code
foo_vector.push_back( FooPtr(new Foo(3)) );
foo_vector.push_back( FooPtr(new Foo(2)) );
foo_vector.push_back( FooPtr(new Foo(1)) );
The Shared_ptr Example shown here gives the full code for a sample program:
Copy Code
#include
#include
#include
#include
struct Foo
{
Foo( int _x ) : x(_x) {}
~Foo() { std::cout << "Destructing a Foo with x=" << x << "\n"; }
int x;
/* ... */
};
typedef boost::shared_ptr FooPtr;
struct FooPtrOps
{
bool operator()( const FooPtr & a, const FooPtr & b )
{ return a->x <>x; }
void operator()( const FooPtr & a )
{ std::cout << " " <<>x; }
};
int main()
{
std::vector foo_vector;
foo_vector.push_back( FooPtr(new Foo(3)) );
foo_vector.push_back( FooPtr(new Foo(2)) );
foo_vector.push_back( FooPtr(new Foo(1)) );
std::cout << "Original foo_vector:";
std::for_each( foo_vector.begin(), foo_vector.end(), FooPtrOps() );
std::cout << "\n";
std::sort( foo_vector.begin(), foo_vector.end(), FooPtrOps() );
std::cout << "Sorted foo_vector:";
std::for_each( foo_vector.begin(), foo_vector.end(), FooPtrOps() );
std::cout << "\n";
return 0;
}
The output will be:
Copy Code
Original foo_vector: 3 2 1
Sorted foo_vector: 1 2 3
Destructing a Foo with x=1
Destructing a Foo with x=2
Destructing a Foo with x=3
The library's documentation includes a page on Smart Pointer Programming Techniques that gives many examples of smart pointer usage, including COM and HANDLE examples in a Microsoft® Windows® environment. For any smart pointer used across DLL boundaries, be sure to set the code generation runtime library option (/MD[d]) consistently so that the modules containing both the new and delete share the same runtime heap.
Regular Expressions
The Boost Regular Expression Library, often called regex++, fills a major hole in the C++ Standard Library. Regular expressions perform generalized string pattern matching, and so are nearly essential for string manipulation chores. Here is a simple example from the library's documentation:
Copy Code
bool validate_card_format(const std::string s)
{
static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
return regex_match(s, e);
}
That regular expression basically says "accept a string if it consists of three sets of four digits followed by a hyphen or a space, and ends with another four digits."
In real applications, regular expressions are often much more complicated. For instance, here is an example for a regular expression that can parse C++ source code and extract class definitions, with class names and specializations identified. This Regular Expression Example comes from several of the library's example programs, which use it to extract class information from C++ program code.
Copy Code
const char* re =
// possibly leading whitespace:
"^[[:space:]]*"
// possible template declaration:
"(template[[:space:]]*<[^;:{]+>[[:space:]]*)?"
// class or struct:
"(classstruct)[[:space:]]*"
// leading declspec macros etc:
"("
"\\<\\w+\\>"
"("
"[[:blank:]]*\\([^)]*\\)"
")?"
"[[:space:]]*"
")*"
// the class name
"(\\<\\w*\\>)[[:space:]]*"
// template specialisation parameters
"(<[^;:{]+>)?[[:space:]]*"
// terminate in { or :
"(\\{:[^;\\{()]*\\{)";
Since the Microsoft® .NET Framework also supplies a regular expression library, should a Visual C++ programmer use it or the Boost library? That probably depends on the application. An application that may someday be ported to other platforms or may be maintained by programmers unfamiliar with .NET might want to use the Boost library. For pure .NET applications, it may make more sense to stick with the Microsoft regular expressions.
Type Traits
The Boost Type Traits library helps programmers manipulate type information at compile time. It has also been accepted for the Library Technical Report. Uses include supporting a wider variety of types in user-written templates, adding compile-time assertions to improve error detection, and enabling optimizations.
Type traits work by providing templates with a value member that will be true or false. For example:
Copy Code
boost::is_integral::value
If the type T is an integral type according to the language rules, that expression will evaluate to true; otherwise it will evaluate to false. Because it is a compile-time expression, it can be used to alter the course of compilation. That allows use in many generic and metaprogramming contexts. The table below lists all the Boost type traits.
Table 1. Type traits
Primary type categories
Secondary type categories
Type properties
Relationships between types
Transformations to type
is_voidis_integralis_floatis_pointeris_referenceis_member_pointeris_arrayis_unionis_classis_enumis_function
is_arithmeticis_fundamentalis_objectis_scalaris_compoundis_member_function_pointer
is_emptyis_constis_volatileis_polymorphicis_podis_abstracthas_trivial_constructorhas_trivial_copyhas_trivial_assignhas_trivial_destructoris_statelesshas_nothrow_constructorhas_nothrow_copyhas_nothrow_assign
is_sameis_convertibleis_base_and_derived
remove_constremove_volatileremove_cvremove_referenceremove_boundsremove_pointeradd_referenceadd_pointeradd_constadd_volatileadd_cv
The Type Traits Example shown below shows type traits used with the BOOST_STATIC_ASSERT macro to check the validity of a template parameter. Because the check is performed at compile time, there is no run-time cost whatsoever.
Copy Code
#include
#include
template<>
void foo( T value)
{
// foo() requires T be integral type
BOOST_STATIC_ASSERT( boost::is_integral::value );
// ... actual computations
}
int main()
{
int i;
float f;
foo( i );
foo( f ); // error! integral type required
return 0;
}
Metaprogramming
Metaprogramming can be loosely defined as "programs that generate programs." Metaprograms run at compile time, tailoring the code that is actually compiled into the final program. Until recently, metaprogramming was an exotic technique known only to a few researchers, but now C++ metaprogramming is becoming more mainstream with libraries available to handle the details. Boost's metaprogramming libraries provide both preprocessor metaprogramming and template metaprogramming facilities.
The Boost Template Metaprogramming Library (MPL) provides a wealth of operations on types, including control flow, containers, iterators, and algorithms. Here is an example, adapted from the MPL documentation:
Copy Code
template<>
class auto_size_example
: private mpl::if_< sizeof(T) <= sizeof(double)
, stack_implementation
, heap_implementation
>::type
{
// ...
};
When an auto_size_example template is instantiated at compile time, MPL's if_ will determine whether to inherit from stack_implementation or heap_implementation depending on the size of the template parameter T. The net result is an optimization that would be difficult to perform otherwise.
Other Interesting Boost Libraries
Some of the Boost libraries address specific problem domains that not every programmer cares about. For example, the Boost Spirit Library is of interest only to those who need a parser generator, at least at first glance. But Spirit allows extended BNF grammars to be expressed directly in C++, and as such is a considerable intellectual achievement worth studying just for the joy of viewing a world-class design. The Boost Graph Library is another major effort, and a great example of how generic programming concepts can be applied.
In addition to their usefulness, Boost is full of libraries large and small worth studying as design cases. One of the unanticipated benefits of Boost is that it has brought together experienced software developers and innovative academic researchers. That combination has resulted in library designs that are practical yet creative. It isn't uncommon for programmers to read the Boost mailing lists or newsgroups just to watch new Boost library designs evolve.
Using Boost with Visual C++
The first step is to upgrade to Visual C++ .NET 2003. Earlier Visual C++ versions didn't support partial specialization and other template features required by many Boost libraries, making use difficult.
Installing Boost begins by downloading and unzipping the distribution file. A Boost directory tree will be created exactly equivalent to the Web site and containing all files, including sources and documentation.
Many Boost libraries are entirely implemented in their headers, so the only preparation for use beyond downloading and unzipping is to add the Boost root directory to the list of include paths. In the Visual C++ IDE, click Tools Options... Projects VC++ directories. Then in Show Directories for, select Include files and add the path to the Boost root directory.
At that point, you should be ready to use the header-only Boost libraries. You can build and run the Shared_ptr Example shown earlier to verify your set up is complete.
Some of the Boost code does live in object libraries, and so requires a preparatory build. The Boost distribution includes bjam, a powerful and portable make replacement. The scripts (called Jamfiles) to build Boost object libraries are supplied. If Visual C++ is the only compiler you care about, some of the Boost libraries supply make files to build Visual C++ object libraries directly. Boost object library build and install procedures are a weak point at the moment, so expect a few bumps on the road.
Tips for Getting the Most Out of Boost Libraries
Boost libraries develop over time. Sometimes interfaces change, and when a better idea surfaces, an entire library may undergo extensive changes. The older libraries tend to be quite stable, but even so are subject to some change if they become subject to ISO standardization. Rather than take a chance on breaking your existing code, freeze the Boost version your project uses, and only upgrade to a new Boost release when your project is at a point in its lifecycle where a bit of change won't be a problem. If you need a fix for a specific problem, check the Boost CVS to see if a specific fix is available. Because the entire Boost development process is public, you can also ask Boost developers for help with specific problems. There are several mailing lists for support, and these can also be accessed by Web newsgroups. See the Boost Web site for details.
Contributing to Boost
Boost depends on volunteer programmers contributing time and effort; there is no paid staff and the budget is exactly zero. There are a lot of different ways you can contribute to Boost. The most obvious is to contribute a library. But other forms of contribution are equally important.
To be accepted by Boost, libraries go through a formal review process. Anyone can contribute a formal review, and that's a great way to help Boost. Some experienced Boost users help by answering questions from new uses on the Boost-Users mailing list and newsgroup. Some of the larger Boost libraries have their own mailing lists and teams of developers. The best way to get started is to read the main developers mailing list for a while to see how the Boost process works.
Conclusion
The much improved C++ language compliance of Visual C++ .NET 2003 allows full use of the Boost libraries by Visual C++ developers. These community-developed libraries cover a spectrum of needs, ranging from everyday to very specialized. They can be huge productivity boosters, they have interesting designs, and the Boost libraries are absolutely free.
Related Books
Microsoft Visual C++ .Net 2003 Kick Start by Kate Gregory
C++ Templates: The Complete Guide by David Vandevoorde and Nicolai M. Josuttis
The Boost Graph Library: User Guide and Reference by Jeremy G Siek
Appendix: The C++ Standard Library Technical Report (TR)
The C++ Standard Library Technical Report is the ISO C++ Committee's way of gently adding new features to the C++ Standard Library. The additions are "non-normative," meaning that vendors don't have to supply them, although most will. A TR can move through the ISO standardization process more rapidly than a full update to the standard.
Technical Reports often become part of the official standard at a later date. Think of them as 0.9 versions of future releases.
Although details of the Library TR are still being finalized, it looks like most components will be in namespace TR1. When the TR libraries later become full-fledged parts of the Standard Library, they will move to namespace std. This allows the libraries to be changed without breaking existing code. User experience with the TR will determine if such changes are necessary.
A list of libraries that will be in the Library TR is available on the ISO C++ public Web site.

About the author
Beman Dawes is a software developer from Virginia in the United States and the founder of boost.org. He is the author of the StreetQuick® geographic atlas library used by digital map publishers to help people get really, really, lost. Beman has been a voting member of the ANSI/ISO C++ Standards Committee since 1992, and chaired the Library Working Group for five years.
© 2009 Microsoft Corporation. All rights reserved. Terms of Use Trademarks Privacy Statement

댓글 없음:

댓글 쓰기