SlideShare ist ein Scribd-Unternehmen logo
1 von 20
Downloaden Sie, um offline zu lesen
C++ Tutorial - Boost – 2013
mmittee's Library Technical Report 1 (TR1) functionality is based on work done at Boost, and until
vendors of compilers include TR1 in their C++ library distributions, the Boost web site will remain the
first stop for developers looking for TR1 implementation.
Boost libraries range from general-purpose libraries like the smart_ptr library, to operating system
abstractions like Boost FileSystem, to libraries primarily aimed at other library developers and
advanced C++ users, like the template metaprogramming (mpl).
In order to ensure efficiency and flexibility, Boost makes extensive use of templates. Boost has been a
source of extensive work and research into generic programming and metaprogramming in C++.
Here is a summary of what Boost brings to the table:
• Boost provides lots of useful facilities not available in STL.
• Boost provides alternatives to work around certain problems with STL's design or
implementation.
• Boost does a good job of handling some of the very complicated problems, such as smart
pointers.
• Documentation is usually excellent. Not only does the documentation explain what each library
does and how to use it, but it also provides an excellent in-depth discussion of the design
decisions, constraints, and requirements that went into constructing the library. So, reading the
Boost documentation is a great way of learning about the principles of software design.
While Boost can serve as an excellent extension or alternative to many of STL's feature. But we should
be aware of the following caveats:
• Most of the core Boost classes are templates, so all that one needs in order to use them is the
appropriate set of header files. However, some of the Boost libraries built into rather large .lib
files and may not be feasible for use in a very small project.
• Though the world-wide Boost community provides an excellent support, the Boost libraries
come with no guarantees. If we encounter a bug, it will ultimately be our responsibility to work
around it.
• Backward compatibility may not be supported.
• The Boost libraries are distributed under the Boost Software License.
The next section will show how we can start to use boost libraries using Windows environment. Since
there are other good sites for introductory course, I'm not going into details here.
Using Visual Studio 2012 IDE
Download a source from Boost Downloads.
Open up Developer Command Prompt window -> Go to the boost directory.
Issue a command bootstrap, and then b2:
We need to setup include and link library path as indicated in the picture below:

Once installed, let's run our sample code.
Use the following file as our source file, "ex.cpp":
#include
#include
#include
#include

<boost/lambda/lambda.hpp>
<iostream>
<iterator>
<algorithm>
int main()
{
typedef std::istream_iterator<int> in;
std::cout << "Type in any number: ";

}

std::for_each(
in(std::cin), in(), std::cout
<< (boost::lambda::_1 * 10)
<< "nType in another number: " );

Build and Run.
Type some numbers.
Type in any number: 10
100
Type in another number: 20
200
Type in another number:

We got it!
Using Command Line
This time, we're going to do it on command line:
All Programs > Microsoft Visual Studio 2012 >
Visual Studio Tools > Visual Studio 2012 Command Prompt
Then, run the following, we'll have "ex.exe"
In my case, the "ex.cpp" is in C:TESTMyBoost;

TR1 Components
TR1 specifies new components and all are in the boost namespace. For example, the full name of the
shared_ptr is:
boost::shared_ptr

Here is the list of the new components:
smart pointers
A smart pointer is an object that acts like a pointer for most intents and purposes but avoids most of
the problems inherent with C++ pointers. At its simplest, a smart pointer contains a native pointer as a
data member and provides a set of overloaded operators that make it act like a pointer in most ways.
Pointers can be dereferenced, so the * and -> operators are overloaded to return the address as
expected. Pointers can undergo pointer arithmetic operations, so the +, -, ++, and -- operators are also
overloaded appropriately.
Because a smart pointer is an object, it can contain additional meta-data and take additional steps not
possible with a regular pointer. For example, a smart pointer might contain information that allows it to
recognize when the object to which it points has been deleted and start returning a NUll if so.
Smart pointers can also help with object lifetime management by cooperating with one another to
determine the number of references to a particular object. This is called reference counting. When the
number of smart pointers that reference a particular object drops to zero, we know that the object is no
longer needed, so it can be automatically deleted. This can free the programmer from having to worry
about object ownership and orphaned object (an object that still occupied memory but is no longer
needed or referenced by any other object in the system).
Smart pointers have their share of problems. For one thing, they are relatively easy to implement, but
they are extremely tough to get right. There are a great many cases to handle, and the std::auto_ptr class
provided by the standard C++ library is widely recognized to be inadequate in many situations, and it's
now deprecated.
• shared_ptr
The auto_ptr has unusual characters: copying it whether via copy constructor or copy
assignment operator sets it to null, and the copying pointer assumes ownership of the resource
as we see in the example below:
#include <iostream>
#include <memory>
using namespace std;
class A{};
int main()
{
auto_ptr<A> pA(new A);
cout << pA.get() << endl;
auto_ptr<A> pB(pA);
cout << pA.get() << endl;
cout << pB.get() << endl;
return 0;
}

Output is:
001B0950
00000000
001B0950

In the example, the get() method returns a pointer to the object pointed by the auto_ptr object, if
any, or zero if it does not point to any object.
Note that the second output is null. So, in the copy constructor, pA transferred the ownership of
A object to pB.
This behavior and the underlying requirement that resources managed by auto_ptrs must never
have more than one auto_ptr pointing to them, means that auto_ptrs aren't the best way to
handle resources which are dynamically allocated.
So, as an alternative to auto_ptr, we have a referencing-counting smart pointer. It keeps
track of how many objects point to a particular resource and deletes the resource automatically
when nothing is pointing to it.
By replacing auto_ptr with share_ptr, with an almost same code below, it produces the output
we want to:
#include <boost/smart_ptr/shared_ptr.hpp>
#include <iostream>
#include <memory>
class A{};
int main()
{
boost::shared_ptr<A> pA(new A);
std::cout << pA.get() << std::endl;
boost::shared_ptr<A> pB(pA);
std::cout << pA.get() << std::endl;
std::cout << pB.get() << std::endl;
}

return 0;

Output is:
002C0950
002C0950
002C0950

Since copying boost::shared_ptr works as we expect, it can be used in STL containers while
we cannot use std::auto_ptr for STL containers.
The major problem being solved using share_ptr is to know the correct time to delete a
resource that is shared. The following example has two classes, A and B. The classes are
sharing an instance of int, and store a shared_ptr<int>. When we create the instances of each
class, the shared_ptr pTemp is passed to the constructors. In other words, all three
shared_ptrs, are now referring to the same instance of an int. If we had used pointers to
achieve such sharing of an int, each class would have had a hard time figuring out when it
should be deleted. In the example, until the end of main(), the reference count is 3. If all of the
pointers go out of scope, the reference count reaches 0, allowing the shared instance of int to be
deleted.
shared_ptr holds an internal pointer to a resource such as a dynamically allocated object that
may be shared with other objects in the program. We can have any number of shared_ptrs to
the same resource. shared_ptr really does share the resource, if we change the resource with
one shared_ptr, the changes also will be seen by the other shared_ptrs. The internal pointer is
deleted once the last shared_ptr to the resource is destroyed. shared_ptr uses reference
counting to determine how many shared_ptrs point to the resource. Each time a new
shared_ptr to the resource is created, the reference count increases, and each time one is
destroyed, the reference count decreases. When the reference count reaches zero, the internal
pointer is deleted and the memory is released.
#include <boost/smart_ptr/shared_ptr.hpp>;
#include <iostream>
#include <memory>
class classA
{
boost::shared_ptr<int> ptA;
public:
classA(boost::shared_ptr<int> p) : ptA(p) {}
void setValue(int n) {
*ptA = n;
}
};
class classB
{
boost::shared_ptr<int> ptB;
public:
classB(boost::shared_ptr<int> p) : ptB(p) {}
int getValue() const {
return *ptB;
}
};
int main()
{
boost::shared_ptr<int> pTemp(new int(2013));
classA a(pTemp);
classB b(pTemp);
a.setValue(2014);
std::cout << "b.getValue() = " << b.getValue() << std::endl;
}

return 0;

Output is:
b.getValue() = 2014

shared_ptr also allows us to determine how the resource will be destroyed. For most
dynamically allocated objects, delete is used. However, some resources require more complex
cleanup. In that case, we can supply a custom deleter function, or function object, to the
shared_ptr destructor. The deleter determines how to destroy the resource. When the reference
count reaches zero and the resource is ready to be destroyed, the shared_ptr calls the custom
deleter function. This functionality enables a shared_ptr to manage almost any kind of
resource.
For dynamically allocated arrays, we shouldn't use either of them because they use delete in
their destructor but not delete[]. We can use vector instead. If we insist on using boost, we can
use either boost::shared_array or boost::scoped_array.
• shared_array
A pointer to an array of objects whose lifetimes are shared by multiple owners.
• scoped_ptr
A pointer to a single object with one owner.
Let's look at the following timer example used in Design Patterns: Nested Implementation Class
// timer.h
class Timer
{
public:
explicit Timer(double);
~Timer();
private:
class Implementation;
Implementation *pImpl;
};
// timer.cpp
#include "timer.h"
#include <iostream>
#ifdef WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#endif
class Timer::Implementation
{
public:
double elapsedTime()
{
#ifdef WIN32
return (GetTickCount() - mStartTime)/1000 ;
#else
struct timeval endTime;
gettimeofday(&endTime,NULL);
return endTime.tv_sec+(endTime.tv_usec/1000000.0)(mStartTime.tv_sec+(mStartTime.tv_usec/1000000.0)) ;
#endif
}
#ifdef WIN32
DWORD mStartTime;
#else
struct timeval mStartTime;
#endif
double mDuration;
};
Timer::Timer(double d):pImpl(new Timer::Implementation())
{
pImpl->mDuration = d;
#ifdef WIN32
pImpl->mStartTime = GetTickCount();
#else
gettimeofday(&(pImpl->mStartTime), NULL);
#endif
}
Timer::~Timer()
{
while(pImpl->elapsedTime() < pImpl->mDuration) ;
std::cout << pImpl->mDuration << " sec elapsed" << std::endl;
delete pImpl;
pImpl = NULL;
}
// main.cpp
#include "timer.h"
int main()
{
double wait = 5;
Timer *pTimer = new Timer(wait);
delete pTimer;
return 0;
}

As we see in the code above, we allocate Implementation object inside the Timer constructor,
and initialize the private member, pImpl of the class. This approach is error-prone, and every
now an then we may forget to delete the object in our destructor.
Using smart pointers make easier. In other words, we could use a shared pointer or a scoped
pointer to hold the Implementation object pointer.
Here is the new code which is using scope_ptr:
// timer.h
#include <boost/smart_ptr/scoped_ptr.hpp>
class Timer
{
public:
explicit Timer(double);
~Timer();
private:
class Implementation;
//Implementation *pImpl;
boost::scoped_ptr<Implementation> pImpl;
};
// timer.cpp
#include "timer.h"
#include <iostream>
#ifdef WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#endif
class Timer::Implementation
{
public:
double elapsedTime()
{
#ifdef WIN32
return (GetTickCount() - mStartTime)/1000 ;
#else
struct timeval endTime;
gettimeofday(&endTime,NULL);
return endTime.tv_sec+(endTime.tv_usec/1000000.0)(mStartTime.tv_sec+(mStartTime.tv_usec/1000000.0)) ;
#endif
}
#ifdef WIN32
DWORD mStartTime;
#else
struct timeval mStartTime;
#endif
double mDuration;
};
Timer::Timer(double d):pImpl(new Timer::Implementation())
{
pImpl->mDuration = d;
#ifdef WIN32
pImpl->mStartTime = GetTickCount();
#else
gettimeofday(&(pImpl->mStartTime), NULL);
#endif
}
Timer::~Timer()
{
while(pImpl->elapsedTime() < pImpl->mDuration) ;
std::cout << pImpl->mDuration << " sec elapsed" << std::endl;
// delete pImpl;
// pImpl = NULL;
}
// main.cpp
#include "timer.h"
int main()
{
double wait = 5;
Timer *pTimer = new Timer(wait);
delete pTimer;
return 0;
}

We could have used a boost::shared_ptr, which would mean that any copy would point to the
same Implementation object. In any case, using either a shared_ptr or a scoped_ptr means
that the Implementation object will be freed automatically when the object is destroyed. So, we
no longer need to delete it in the destructor as shown in commented lines of the new code,
Timer::~Timer().
• scoped_array
A pointer to an array of objects with one owner.
• weak_ptr
A pointer that does not own or automatically destroy the object it references (whose lifetime is
assumed to be managed by a shared_ptr). We could think it as a shared_ptr observer.
A weak_ptr points to the resource managed by a shared_ptr without assuming any
responsibility for it. The reference count for a shared_ptr doesn't increase when a weak_ptr
references it. That means that the resource of a shared_ptr can be deleted while there are still
weak_ptr pointing to it. When the last shared_ptr is destroyed, the resource is deleted and any
remaining weak_ptr are set to NULL. One use for weak_ptr, as shown in the example below,
is to avoid memory leaks caused by circular references.
A weak_ptr can't directly access the resource it points to, we must create a shared_ptr from the
weak_ptr to access the resource. There are two ways to do this.
• We can pass the weak_ptr to the shared_ptr constructor. That creates a shared_ptr to
the resource being pointed to by the weak_ptr and properly increases the reference
count. If the resource has already been deleted, the shared_ptr constructor will throw a
boost::bad_weak_ptr exception.
• We can also call the weak_ptr member function lock(), which returns a shared_ptr to
the weak_ptr's resource. If the weak_ptr points to a deleted resource, lock will return
an empty shared_ptr. The lock() should be used when an empty shared_ptr isn't
considered an error. We can access the resource once you have a shared_ptr to it. This
approach is shown in the example below.
weak_ptr should be used in any situation where we need to observe the resource but don't want
to assume any management responsibilities for it. The example shows the use of weak_ptrs in
circularly referential data, a situation in which two objects refer to each other internally.
In the example below, we define classes Singer and Song. Each class has a pointer to an
instance of the other class. This creates a circular reference between the two classes. Note that
we use both weak_ptr and shared_ptr to hold the cross reference to each class.
Classes Singer and Song define destructors that each display a message to indicate when an
instance of either class is destroyed. Each class also defines a member function to print the title
of the Song and Singer's name. Because we can't access the resource directly through a
weak_ptr, first we create a shared_ptr from the weak_ptr data member lock(). If the resource
the weak_ptr is referencing doesn't exist, the call to the lock() function returns a shared_ptr
which points to NULL and the condition fails. Otherwise, the new shared_ptr contains a valid
pointer to the weak_ptr's resource, and we can access the resource. If the condition is true
(when both songPtr and singerPtr aren't NULL), we print the reference count to show that it
increased with the creation of the new shared_ptr, then we print the title of the Song and
Singer's name. The shared_ptr is destroyed when the function exits so the reference count
decreases by one.
Here are the codes:
Singer.h
#ifndef SINGER_H
#define SINGER_H
#include <string>
using std::string;
#include "boost/shared_ptr.hpp"
#include "boost/weak_ptr.hpp"
class Song;
class Singer
{
public:
Singer::Singer(const string &SingerName);
~Singer();
void printSongTitle() ;
string name;
boost::weak_ptr<Song> weakSongPtr;
boost::shared_ptr<Song> sharedSongPtr;
};
#endif

Song.h
#ifndef SONG_H
#define SONG_H
#include <string>
using std::string;
#include "boost/shared_ptr.hpp"
#include "boost/weak_ptr.hpp"
class Singer; // forward declaration
class Song
{
public:
Song(const string &SongTitle) ;
~Song();
};
#endif

void printSingerName();
string title;
boost::weak_ptr<Singer> weakSingerPtr;
boost::shared_ptr<Singer> sharedSingerPtr;

Singer.cpp
#include <string>
using namespace std;
#include "boost/shared_ptr.hpp"
#include "boost/weak_ptr.hpp"
#include "Song.h"
#include "Singer.h"
Singer::Singer(const string &SingerName) : name(SingerName)
{
cout << "Singer constructor: " << name << endl;
}
Singer::~Singer()
{
cout << "Singer destructor: " << name << endl;
}
void Singer::printSongTitle()
{
// if weaksongPtr.lock() returns a non-empty shared_ptr
if (boost::shared_ptr<Song> songPtr = weakSongPtr.lock()) {
cout << "Reference count for song " << songPtr->title
<< " is " << songPtr.use_count() << "." << endl;
cout << "Singer " << name << " wrote the song " << songPtr>title << "nn";
}
else // weaksongPtr points to NULL
cout << "This Singer has no song." << endl;
}

Song.cpp
#include <string>
using namespace std;
#include "boost/shared_ptr.hpp"
#include "boost/weak_ptr.hpp"
#include "Song.h"
#include "Singer.h"
Song::Song(const string &SongTitle) : title(SongTitle)
{
cout << "Song constructor: " << title << endl;
}
Song::~Song()
{
cout << "Song destructor: " << title << endl;
}
void Song::printSingerName()
{
// if weakSingerPtr.lock() returns a non-empty shared_ptr
if (boost::shared_ptr<Singer> singerPtr = weakSingerPtr.lock() ) {
// show the reference count increase and print the Singer's
name
cout << "Reference count for Singer " << singerPtr->name
<< " is " << singerPtr.use_count() << "." << endl;
cout << "The Song " << title << " was written by "
<< singerPtr->name << "n" << endl;
}
else // weakSingerPtr points to NULL
cout << "This Song has no Singer." << endl;
}

main.cpp
#include <iostream>
#include <string>
#include "boost/shared_ptr.hpp"
#include "boost/weak_ptr.hpp"
#include "Singer.h"
#include "Song.h"
using namespace std;
int main()
{
cout << "Creating a Song and an Singer ..." << endl;
boost::shared_ptr<Song> SongPtr( new Song( "The Boys" ) );
boost::shared_ptr<Singer> SingerPtr(new Singer( "Girls Generation" )
);
cout << "nReferencing the Song and Singer to each other..." <<
endl;

SongPtr->weakSingerPtr = SingerPtr;
SingerPtr->weakSongPtr = SongPtr;

cout << "nSetting the shared_ptr data members to create the memory
leak..." << endl;
SongPtr->sharedSingerPtr = SingerPtr;
SingerPtr->sharedSongPtr = SongPtr;
cout << "Reference count for SongPtr and SingerPtr should be one,
but ... " << endl;
cout << "Reference count for Song " << SongPtr->title << " is "
<< SongPtr.use_count() << endl;
cout << "Reference count for Singer " << SingerPtr->name << " is "
<< SingerPtr.use_count() << "n" << endl;
cout << "nAccess the Singer's name and the Song's title through "
<< "weak_ptrs." << endl;
SongPtr->printSingerName();
SingerPtr->printSongTitle();
cout << "Reference count for each shared_ptr shoulb be back to one:"
<< endl;
cout << "Reference count for Song " << SongPtr->title << " is "
<< SongPtr.use_count() << endl;
cout << "Reference count for Singer " << SingerPtr->name << " is "
<< SingerPtr.use_count() << "n" << endl;
// the shared_ptrs go out of scope, the Song and Singer are
destroyed
cout << "The shared_ptrs are going out of scope." << endl;
return 0;
}

In main(), we see the memory leak caused by the circular reference between classes Singer and
Song. The lines:
boost::shared_ptr<Song> SongPtr( new Song( "The Boys" ) );
boost::shared_ptr<Singer> SingerPtr(new Singer( "Girls Generation" ) );

create shared_ptrs to an instance of each class. The weak_ptr data members are set as:
SongPtr->weakSingerPtr = SingerPtr;
SingerPtr->weakSongPtr = SongPtr;

The shared_ptr data members for each class are set in the lines below.
SongPtr->sharedSingerPtr = SingerPtr;
SingerPtr->sharedSongPtr = SongPtr;

The instances of classes Singer and Song now reference each other. We then print the reference
count for the shared_ptr to show that each instance is referenced by two shared_ptrs
cout <<
<<
cout <<
<<

"Reference count for Song " << SongPtr->title << " is "
SongPtr.use_count() << endl;
"Reference count for Singer " << SingerPtr->name << " is "
SingerPtr.use_count() << "n" << endl;

the ones we create in the main() and the data member of each instance. Recall that weak_ptr
don't affect the reference count. Then we call each class's member function to print the
information stored in the weak_ptr data member:
SongPtr->printSingerName();
SingerPtr->printSongTitle();

The functions also display the fact that another shared_ptr was created during the function call.
Finally, we print the reference counts again to show that the additional shared_ptrs created in
the printSingerName and printSongTitle member functions are destroyed when the functions
finish.
cout << "Reference count for Song " << SongPtr->title << " is "
<< SongPtr.use_count() << endl;
cout << "Reference count for Singer " << SingerPtr->name << " is "
<< SingerPtr.use_count() << "n" << endl;

The output is:
Creating a Song and an Singer ...
Song constructor: The Boys
Singer constructor: Girls Generation
Referencing the Song and Singer to each other...
Setting the shared_ptr data members to create the memory leak...
Reference count for SongPtr and SingerPtr should be one, but ...
Reference count for Song The Boys is 2
Reference count for Singer Girls Generation is 2
Access the Singer's name and the Song's title through weak_ptrs.
Reference count for Singer Girls Generation is 3.
The Song The Boys was written by Girls Generation
Reference count for song The Boys is 3.
Singer Girls Generation wrote the song The Boys
Reference count for each shared_ptr shoulb be back to one:
Reference count for Song The Boys is 2
Reference count for Singer Girls Generation is 2
The shared_ptrs are going out of scope.

At the end of main(), the shared_ptr to the instances of Singer and Song we created go out of
scope and are destroyed. Notice that the output doesn't show the destructors for classes Singer
and Song. The program has a memory leak, in other words, the instances of Singer and Song
aren't destroyed because of the shared_ptr data members. When songPtr is destroyed at the
end of the main(), the reference count for the instance of class Song becomes one because the
instance of Singer still has a shared_ptr to the instance of Song, so it's not deleted. When
singerPtr goes out of scope and is destroyed, the reference count for the instance of class
Singer also becomes one because the instance of Song still has a shared_ptr to the instance of
Singer. Neither instance is deleted because the reference count for each is still one.
Now, comment out the following lines:
//SongPtr->sharedSingerPtr = SingerPtr;
//SingerPtr->sharedSongPtr = SongPtr;

This prevents the code from setting the shared_ptr data members for classes Singer and Song.
Then, we'll have a new output:
Creating a Song and an Singer ...
Song constructor: The Boys
Singer constructor: Girls Generation
Referencing the Song and Singer to each other...
Setting the shared_ptr data members to create the memory leak...
Reference count for SongPtr and SingerPtr should be one, but ...
Reference count for Song The Boys is 1
Reference count for Singer Girls Generation is 1
Access the Singer's name and the Song's title through weak_ptrs.
Reference count for Singer Girls Generation is 2.
The Song The Boys was written by Girls Generation
Reference count for song The Boys is 2.
Singer Girls Generation wrote the song The Boys
Reference count for each shared_ptr shoulb be back to one:
Reference count for Song The Boys is 1
Reference count for Singer Girls Generation is 1
The shared_ptrs are going out of scope.
Singer destructor: Girls Generation
Song destructor: The Boys

Notice that the initial reference count for each instance is now one instead of two because we
don't set the shared_ptr data members. The last two lines of the output show that the instances
of classes Singer and Song were destroyed at the end of the main(). We eliminated the memory
leak by using the weak_ptr data members rather than the shared_ptr data members. The
weak_ptr don't affect the reference count but still allow us to access the resource when we need
it by creating a temporary shared_ptr to the resource. When the shared_ptr we created in
main() are destroyed, the reference counts become zero and the instances of classes Singer and
Song are deleted properly.
• intrusive_ptr
A pointer that implements reference counting by assuming that the pointed-to object will
maintain the reference count itself. Intrusive pointers are useful because they are the same size
as the native C++ pointer (no reference-counting mechanism is required), and because they can
be constructed directly from native pointers.
Properly implementing a smart pointer class can be a daunting task, and all sorts of issues come up,
including:
•
•
•
•

type safety of smart pointers
the ability for a smart pointer to be used with an incomplete type
correct smart pointer behavior when an exception occurs.
runtime costs, which can be high

smart pointers - pros and cons
This is from Google C++ Style Guide.
Smart pointers are objects that act like pointers, but automate management of the underlying memory.
If we actually need pointer semantics, scoped_ptr is great. We should only use std::tr1::shared_ptr
with a non-const referent when it is truly necessary to share ownership of an object (e.g. inside an STL
container). We should never use auto_ptr.
• Pros
Smart pointers are extremely useful for preventing memory leaks, and are essential for writing
exception-safe code. They also formalize and document the ownership of dynamically
allocated memory.
• Cons
We prefer designs in which objects have single, fixed owners. Smart pointers which enable
sharing or transfer of ownership can act as a tempting alternative to a careful design of
ownership semantics, leading to confusing code and even bugs in which memory is never
deleted. The semantics of smart pointers (especially auto_ptr) can be nonobvious and
confusing. The exception-safety benefits of smart pointers are not decisive, since we do not
allow exceptions.
• Decision
• scoped_ptr
Straightforward and risk-free. Use wherever appropriate.
• auto_ptr
Confusing and bug-prone ownership-transfer semantics. Do not use.
• shared_ptr
Safe with const referents (i.e. shared_ptr<const T>). Reference-counted pointers with
non-const referents can occasionally be the best design, but try to rewrite with single
owners where possible.

boost::lambda
There are several libraries which are function objects and higher-order programming. They are used as
the basis for functionality in TR1. One of those libraries is the Lambda library, which makes it so easy
to create function objects on the fly:
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
using namespace std;
void makeSquare(vector<int>&v)
{
for_each(v.begin(), v.end(), cout << boost::lambda::_1*boost::lambda::_1
<< " ");
}
int main()
{
vector<int> v;
for(int i = 1; i <= 10; i++) v.push_back(i);

}

makeSquare(v);
return 0;

Output is:
1 4 9 16 25 36 49 64 81 100

For each element x in v, print x*x:
boost::lambda::_1*boost::lambda::_1

_1 is the Lambda library's placeholder for the current element.
boost::mpl
The boost::mpl is a high-level C++ template metaprogramming framework of compile-time
algorithms, sequences and metafunctions.
Here is an example of calculating a factorial during compilation. It demonstrates looping through
recursive template instantiation. It also demonstrates one way in which variables are created and used
in template metaprogramming (TMP):
#include <iostream>
template <int n>
struct Factorial
{
enum { value = n * Factorial<n - 1>::value };
};
template <>
struct Factorial<0>
{
enum { value = 1 };
};
int main()
{
std::cout << "Factorial<5>::value = " << Factorial<5>::value << std::endl;
}

The first template is for the general case, and the value of Factorial<n> is n times the value of
Factorial<n-1>. The second template is for a special case, which is a template specialization to provide
the ending condition for the recursion, and the value of Factorial<0> is 1.
Note that it calculates factorials at compile time. However, to be able to use templates in this manner,
the compiler must know the value of its parameters at compile time, which has the natural precondition
that Factorial<n>::value can only be used if n is known at compile time. In other words, n must be a
constant literal or a constant expression.
The looping occurs where the template instantiation Factorial<n> references the template instantiation
Factorial<n-1>. Each instantiation of the Factorial template is a struct, and each struct uses the enum
to declare a template metaprogramming variable named value. This variable value is what holds the
current value of the factorial calculation.
Since template metaprogramming uses recursive template instantiation in place of loops, each
instantiation gets its own copy of value, and each copy has the proper value for its place in the loop.
boost::function
boost::bind
Hash tables
Regular expressions - boost::regex
• E-mail
b[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z]{2,4}b
or more general expression
b[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}b

• ip address
to match 999.999.999.999
bd{1,3}.d{1,3}.d{1,3}.d{1,3}b
or To restrict all 4 numbers in the IP address to 0..255
b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][09]?).
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][09]?)b

Tuples
boost::array
boost::mem_fn
boost::reference_wrapper
Random number generation
Mathematical special functions
C99 compatibility extensions
Type traits
boost::result_of
Boost - pros and cons
The followings are from C++ style guide
The Boost library collection is a popular collection of peer-reviewed, free, open-source C++ libraries.
Use only approved libraries from the Boost library collection.
• Pros
Boost code is generally very high-quality, is widely portable, and fills many important gaps in
the C++ standard library, such as type traits, better binders, and better smart pointers. It also
provides an implementation of the TR1 extension to the standard library.
• Cons
Some Boost libraries encourage coding practices which can hamper readability, such as
metaprogramming and other advanced template techniques, and an excessively functional
style of programming.
• Decision
In order to maintain a high level of readability for all contributors who might read and maintain
code, we only allow an approved subset of Boost features. Currently, the following libraries are
permitted:
• Call Traits from boost/call_traits.hpp.
• Compressed Pair from boost/compressed_pair.hpp.
• Pointer Container from boost/ptr_containerexcept serialization and wrappers for
containers
not in the C++03 standard (ptr_circular_buffer.hpp
and ptr_unordered*).
• Array from boost/array.hpp.
• The Boost Graph Library (BGL) from boost/graph, except serialization
(adj_list_serialize.hpp)
and parallel/distributed algorithms and data structures (boost/graph/parallel/*
and boost/graph/distributed/*).
• Property Map from boost/property_map,
except parallel/distributed property maps (boost/property_map/parallel/*).
• The part of Iterator that deals with defining iterators:
boost/iterator/iterator_adaptor.hpp, boost/iterator/iterator_facade.hpp,
and boost/function_output_iterator.hpp.

Weitere ähnliche Inhalte

Was ist angesagt?

Python interview questions and answers
Python interview questions and answersPython interview questions and answers
Python interview questions and answersRojaPriya
 
What’s eating python performance
What’s eating python performanceWhat’s eating python performance
What’s eating python performancePiotr Przymus
 
Data Science Amsterdam - Massively Parallel Processing with Procedural Languages
Data Science Amsterdam - Massively Parallel Processing with Procedural LanguagesData Science Amsterdam - Massively Parallel Processing with Procedural Languages
Data Science Amsterdam - Massively Parallel Processing with Procedural LanguagesIan Huston
 
Python Interview Questions And Answers 2019 | Edureka
Python Interview Questions And Answers 2019 | EdurekaPython Interview Questions And Answers 2019 | Edureka
Python Interview Questions And Answers 2019 | EdurekaEdureka!
 
Combinators, DSLs, HTML and F#
Combinators, DSLs, HTML and F#Combinators, DSLs, HTML and F#
Combinators, DSLs, HTML and F#Robert Pickering
 
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...Maulik Borsaniya
 
Python interview questions
Python interview questionsPython interview questions
Python interview questionsPragati Singh
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndEdward Chen
 
1. python programming
1. python programming1. python programming
1. python programmingsreeLekha51
 
Intro To C++ - Class #17: Pointers!, Objects Talking To Each Other
Intro To C++ - Class #17: Pointers!, Objects Talking To Each OtherIntro To C++ - Class #17: Pointers!, Objects Talking To Each Other
Intro To C++ - Class #17: Pointers!, Objects Talking To Each OtherBlue Elephant Consulting
 
Intro to Python Programming Language
Intro to Python Programming LanguageIntro to Python Programming Language
Intro to Python Programming LanguageDipankar Achinta
 
Basic of python for data analysis
Basic of python for data analysisBasic of python for data analysis
Basic of python for data analysisPramod Toraskar
 

Was ist angesagt? (20)

Python interview questions and answers
Python interview questions and answersPython interview questions and answers
Python interview questions and answers
 
What’s eating python performance
What’s eating python performanceWhat’s eating python performance
What’s eating python performance
 
Python cheat-sheet
Python cheat-sheetPython cheat-sheet
Python cheat-sheet
 
Data Science Amsterdam - Massively Parallel Processing with Procedural Languages
Data Science Amsterdam - Massively Parallel Processing with Procedural LanguagesData Science Amsterdam - Massively Parallel Processing with Procedural Languages
Data Science Amsterdam - Massively Parallel Processing with Procedural Languages
 
Python basics
Python basicsPython basics
Python basics
 
See through C
See through CSee through C
See through C
 
Computer Science Assignment Help
 Computer Science Assignment Help  Computer Science Assignment Help
Computer Science Assignment Help
 
Python Interview Questions And Answers 2019 | Edureka
Python Interview Questions And Answers 2019 | EdurekaPython Interview Questions And Answers 2019 | Edureka
Python Interview Questions And Answers 2019 | Edureka
 
Combinators, DSLs, HTML and F#
Combinators, DSLs, HTML and F#Combinators, DSLs, HTML and F#
Combinators, DSLs, HTML and F#
 
Python Homework Help
Python Homework HelpPython Homework Help
Python Homework Help
 
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...PYTHON -Chapter 2 - Functions,   Exception, Modules  and    Files -MAULIK BOR...
PYTHON -Chapter 2 - Functions, Exception, Modules and Files -MAULIK BOR...
 
Python interview questions
Python interview questionsPython interview questions
Python interview questions
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2nd
 
1. python programming
1. python programming1. python programming
1. python programming
 
Intro To C++ - Class #17: Pointers!, Objects Talking To Each Other
Intro To C++ - Class #17: Pointers!, Objects Talking To Each OtherIntro To C++ - Class #17: Pointers!, Objects Talking To Each Other
Intro To C++ - Class #17: Pointers!, Objects Talking To Each Other
 
Intro to Python Programming Language
Intro to Python Programming LanguageIntro to Python Programming Language
Intro to Python Programming Language
 
Python Basics
Python BasicsPython Basics
Python Basics
 
Basic of python for data analysis
Basic of python for data analysisBasic of python for data analysis
Basic of python for data analysis
 
Python basic
Python basicPython basic
Python basic
 
Python libraries
Python librariesPython libraries
Python libraries
 

Ähnlich wie C++ tutorial boost – 2013

Ähnlich wie C++ tutorial boost – 2013 (20)

Smart pointers
Smart pointersSmart pointers
Smart pointers
 
SRAVANByCPP
SRAVANByCPPSRAVANByCPP
SRAVANByCPP
 
ADK COLEGE.pptx
ADK COLEGE.pptxADK COLEGE.pptx
ADK COLEGE.pptx
 
Bcsl 031 solve assignment
Bcsl 031 solve assignmentBcsl 031 solve assignment
Bcsl 031 solve assignment
 
Introduction Of C++
Introduction Of C++Introduction Of C++
Introduction Of C++
 
Cpp17 and Beyond
Cpp17 and BeyondCpp17 and Beyond
Cpp17 and Beyond
 
Safetty systems intro_embedded_c
Safetty systems intro_embedded_cSafetty systems intro_embedded_c
Safetty systems intro_embedded_c
 
C++ Interview Question And Answer
C++ Interview Question And AnswerC++ Interview Question And Answer
C++ Interview Question And Answer
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answer
 
Technical Interview
Technical InterviewTechnical Interview
Technical Interview
 
08 -functions
08  -functions08  -functions
08 -functions
 
C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1C, C++ Interview Questions Part - 1
C, C++ Interview Questions Part - 1
 
C++ Programming
C++ ProgrammingC++ Programming
C++ Programming
 
C++ Programming
C++ ProgrammingC++ Programming
C++ Programming
 
Process Synchronization Producer-Consumer ProblemThe purpos.docx
Process Synchronization Producer-Consumer ProblemThe purpos.docxProcess Synchronization Producer-Consumer ProblemThe purpos.docx
Process Synchronization Producer-Consumer ProblemThe purpos.docx
 
PRINCE PRESENTATION(1).pptx
PRINCE PRESENTATION(1).pptxPRINCE PRESENTATION(1).pptx
PRINCE PRESENTATION(1).pptx
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
 
Introduction to cpp language and all the required information relating to it
Introduction to cpp language and all the required information relating to itIntroduction to cpp language and all the required information relating to it
Introduction to cpp language and all the required information relating to it
 
Python Evolution
Python EvolutionPython Evolution
Python Evolution
 
Data structure week 1
Data structure week 1Data structure week 1
Data structure week 1
 

Kürzlich hochgeladen

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 

Kürzlich hochgeladen (20)

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 

C++ tutorial boost – 2013

  • 1. C++ Tutorial - Boost – 2013 mmittee's Library Technical Report 1 (TR1) functionality is based on work done at Boost, and until vendors of compilers include TR1 in their C++ library distributions, the Boost web site will remain the first stop for developers looking for TR1 implementation. Boost libraries range from general-purpose libraries like the smart_ptr library, to operating system abstractions like Boost FileSystem, to libraries primarily aimed at other library developers and advanced C++ users, like the template metaprogramming (mpl). In order to ensure efficiency and flexibility, Boost makes extensive use of templates. Boost has been a source of extensive work and research into generic programming and metaprogramming in C++. Here is a summary of what Boost brings to the table: • Boost provides lots of useful facilities not available in STL. • Boost provides alternatives to work around certain problems with STL's design or implementation. • Boost does a good job of handling some of the very complicated problems, such as smart pointers. • Documentation is usually excellent. Not only does the documentation explain what each library does and how to use it, but it also provides an excellent in-depth discussion of the design decisions, constraints, and requirements that went into constructing the library. So, reading the Boost documentation is a great way of learning about the principles of software design. While Boost can serve as an excellent extension or alternative to many of STL's feature. But we should be aware of the following caveats: • Most of the core Boost classes are templates, so all that one needs in order to use them is the appropriate set of header files. However, some of the Boost libraries built into rather large .lib files and may not be feasible for use in a very small project. • Though the world-wide Boost community provides an excellent support, the Boost libraries come with no guarantees. If we encounter a bug, it will ultimately be our responsibility to work around it. • Backward compatibility may not be supported. • The Boost libraries are distributed under the Boost Software License. The next section will show how we can start to use boost libraries using Windows environment. Since there are other good sites for introductory course, I'm not going into details here. Using Visual Studio 2012 IDE Download a source from Boost Downloads. Open up Developer Command Prompt window -> Go to the boost directory. Issue a command bootstrap, and then b2:
  • 2. We need to setup include and link library path as indicated in the picture below: Once installed, let's run our sample code. Use the following file as our source file, "ex.cpp": #include #include #include #include <boost/lambda/lambda.hpp> <iostream> <iterator> <algorithm>
  • 3. int main() { typedef std::istream_iterator<int> in; std::cout << "Type in any number: "; } std::for_each( in(std::cin), in(), std::cout << (boost::lambda::_1 * 10) << "nType in another number: " ); Build and Run. Type some numbers. Type in any number: 10 100 Type in another number: 20 200 Type in another number: We got it! Using Command Line This time, we're going to do it on command line: All Programs > Microsoft Visual Studio 2012 > Visual Studio Tools > Visual Studio 2012 Command Prompt Then, run the following, we'll have "ex.exe" In my case, the "ex.cpp" is in C:TESTMyBoost; TR1 Components TR1 specifies new components and all are in the boost namespace. For example, the full name of the shared_ptr is: boost::shared_ptr Here is the list of the new components:
  • 4. smart pointers A smart pointer is an object that acts like a pointer for most intents and purposes but avoids most of the problems inherent with C++ pointers. At its simplest, a smart pointer contains a native pointer as a data member and provides a set of overloaded operators that make it act like a pointer in most ways. Pointers can be dereferenced, so the * and -> operators are overloaded to return the address as expected. Pointers can undergo pointer arithmetic operations, so the +, -, ++, and -- operators are also overloaded appropriately. Because a smart pointer is an object, it can contain additional meta-data and take additional steps not possible with a regular pointer. For example, a smart pointer might contain information that allows it to recognize when the object to which it points has been deleted and start returning a NUll if so. Smart pointers can also help with object lifetime management by cooperating with one another to determine the number of references to a particular object. This is called reference counting. When the number of smart pointers that reference a particular object drops to zero, we know that the object is no longer needed, so it can be automatically deleted. This can free the programmer from having to worry about object ownership and orphaned object (an object that still occupied memory but is no longer needed or referenced by any other object in the system). Smart pointers have their share of problems. For one thing, they are relatively easy to implement, but they are extremely tough to get right. There are a great many cases to handle, and the std::auto_ptr class provided by the standard C++ library is widely recognized to be inadequate in many situations, and it's now deprecated. • shared_ptr The auto_ptr has unusual characters: copying it whether via copy constructor or copy assignment operator sets it to null, and the copying pointer assumes ownership of the resource as we see in the example below: #include <iostream> #include <memory> using namespace std; class A{}; int main() { auto_ptr<A> pA(new A); cout << pA.get() << endl; auto_ptr<A> pB(pA); cout << pA.get() << endl; cout << pB.get() << endl; return 0; } Output is: 001B0950 00000000
  • 5. 001B0950 In the example, the get() method returns a pointer to the object pointed by the auto_ptr object, if any, or zero if it does not point to any object. Note that the second output is null. So, in the copy constructor, pA transferred the ownership of A object to pB. This behavior and the underlying requirement that resources managed by auto_ptrs must never have more than one auto_ptr pointing to them, means that auto_ptrs aren't the best way to handle resources which are dynamically allocated. So, as an alternative to auto_ptr, we have a referencing-counting smart pointer. It keeps track of how many objects point to a particular resource and deletes the resource automatically when nothing is pointing to it. By replacing auto_ptr with share_ptr, with an almost same code below, it produces the output we want to: #include <boost/smart_ptr/shared_ptr.hpp> #include <iostream> #include <memory> class A{}; int main() { boost::shared_ptr<A> pA(new A); std::cout << pA.get() << std::endl; boost::shared_ptr<A> pB(pA); std::cout << pA.get() << std::endl; std::cout << pB.get() << std::endl; } return 0; Output is: 002C0950 002C0950 002C0950 Since copying boost::shared_ptr works as we expect, it can be used in STL containers while we cannot use std::auto_ptr for STL containers. The major problem being solved using share_ptr is to know the correct time to delete a resource that is shared. The following example has two classes, A and B. The classes are sharing an instance of int, and store a shared_ptr<int>. When we create the instances of each class, the shared_ptr pTemp is passed to the constructors. In other words, all three shared_ptrs, are now referring to the same instance of an int. If we had used pointers to achieve such sharing of an int, each class would have had a hard time figuring out when it should be deleted. In the example, until the end of main(), the reference count is 3. If all of the
  • 6. pointers go out of scope, the reference count reaches 0, allowing the shared instance of int to be deleted. shared_ptr holds an internal pointer to a resource such as a dynamically allocated object that may be shared with other objects in the program. We can have any number of shared_ptrs to the same resource. shared_ptr really does share the resource, if we change the resource with one shared_ptr, the changes also will be seen by the other shared_ptrs. The internal pointer is deleted once the last shared_ptr to the resource is destroyed. shared_ptr uses reference counting to determine how many shared_ptrs point to the resource. Each time a new shared_ptr to the resource is created, the reference count increases, and each time one is destroyed, the reference count decreases. When the reference count reaches zero, the internal pointer is deleted and the memory is released. #include <boost/smart_ptr/shared_ptr.hpp>; #include <iostream> #include <memory> class classA { boost::shared_ptr<int> ptA; public: classA(boost::shared_ptr<int> p) : ptA(p) {} void setValue(int n) { *ptA = n; } }; class classB { boost::shared_ptr<int> ptB; public: classB(boost::shared_ptr<int> p) : ptB(p) {} int getValue() const { return *ptB; } }; int main() { boost::shared_ptr<int> pTemp(new int(2013)); classA a(pTemp); classB b(pTemp); a.setValue(2014); std::cout << "b.getValue() = " << b.getValue() << std::endl; } return 0; Output is: b.getValue() = 2014 shared_ptr also allows us to determine how the resource will be destroyed. For most dynamically allocated objects, delete is used. However, some resources require more complex cleanup. In that case, we can supply a custom deleter function, or function object, to the
  • 7. shared_ptr destructor. The deleter determines how to destroy the resource. When the reference count reaches zero and the resource is ready to be destroyed, the shared_ptr calls the custom deleter function. This functionality enables a shared_ptr to manage almost any kind of resource. For dynamically allocated arrays, we shouldn't use either of them because they use delete in their destructor but not delete[]. We can use vector instead. If we insist on using boost, we can use either boost::shared_array or boost::scoped_array. • shared_array A pointer to an array of objects whose lifetimes are shared by multiple owners. • scoped_ptr A pointer to a single object with one owner. Let's look at the following timer example used in Design Patterns: Nested Implementation Class // timer.h class Timer { public: explicit Timer(double); ~Timer(); private: class Implementation; Implementation *pImpl; }; // timer.cpp #include "timer.h" #include <iostream> #ifdef WIN32 #include <Windows.h> #else #include <sys/time.h> #endif class Timer::Implementation { public: double elapsedTime() { #ifdef WIN32 return (GetTickCount() - mStartTime)/1000 ; #else struct timeval endTime; gettimeofday(&endTime,NULL); return endTime.tv_sec+(endTime.tv_usec/1000000.0)(mStartTime.tv_sec+(mStartTime.tv_usec/1000000.0)) ; #endif }
  • 8. #ifdef WIN32 DWORD mStartTime; #else struct timeval mStartTime; #endif double mDuration; }; Timer::Timer(double d):pImpl(new Timer::Implementation()) { pImpl->mDuration = d; #ifdef WIN32 pImpl->mStartTime = GetTickCount(); #else gettimeofday(&(pImpl->mStartTime), NULL); #endif } Timer::~Timer() { while(pImpl->elapsedTime() < pImpl->mDuration) ; std::cout << pImpl->mDuration << " sec elapsed" << std::endl; delete pImpl; pImpl = NULL; } // main.cpp #include "timer.h" int main() { double wait = 5; Timer *pTimer = new Timer(wait); delete pTimer; return 0; } As we see in the code above, we allocate Implementation object inside the Timer constructor, and initialize the private member, pImpl of the class. This approach is error-prone, and every now an then we may forget to delete the object in our destructor. Using smart pointers make easier. In other words, we could use a shared pointer or a scoped pointer to hold the Implementation object pointer. Here is the new code which is using scope_ptr: // timer.h #include <boost/smart_ptr/scoped_ptr.hpp> class Timer { public: explicit Timer(double); ~Timer(); private: class Implementation;
  • 9. //Implementation *pImpl; boost::scoped_ptr<Implementation> pImpl; }; // timer.cpp #include "timer.h" #include <iostream> #ifdef WIN32 #include <Windows.h> #else #include <sys/time.h> #endif class Timer::Implementation { public: double elapsedTime() { #ifdef WIN32 return (GetTickCount() - mStartTime)/1000 ; #else struct timeval endTime; gettimeofday(&endTime,NULL); return endTime.tv_sec+(endTime.tv_usec/1000000.0)(mStartTime.tv_sec+(mStartTime.tv_usec/1000000.0)) ; #endif } #ifdef WIN32 DWORD mStartTime; #else struct timeval mStartTime; #endif double mDuration; }; Timer::Timer(double d):pImpl(new Timer::Implementation()) { pImpl->mDuration = d; #ifdef WIN32 pImpl->mStartTime = GetTickCount(); #else gettimeofday(&(pImpl->mStartTime), NULL); #endif } Timer::~Timer() { while(pImpl->elapsedTime() < pImpl->mDuration) ; std::cout << pImpl->mDuration << " sec elapsed" << std::endl; // delete pImpl; // pImpl = NULL; } // main.cpp
  • 10. #include "timer.h" int main() { double wait = 5; Timer *pTimer = new Timer(wait); delete pTimer; return 0; } We could have used a boost::shared_ptr, which would mean that any copy would point to the same Implementation object. In any case, using either a shared_ptr or a scoped_ptr means that the Implementation object will be freed automatically when the object is destroyed. So, we no longer need to delete it in the destructor as shown in commented lines of the new code, Timer::~Timer(). • scoped_array A pointer to an array of objects with one owner. • weak_ptr A pointer that does not own or automatically destroy the object it references (whose lifetime is assumed to be managed by a shared_ptr). We could think it as a shared_ptr observer. A weak_ptr points to the resource managed by a shared_ptr without assuming any responsibility for it. The reference count for a shared_ptr doesn't increase when a weak_ptr references it. That means that the resource of a shared_ptr can be deleted while there are still weak_ptr pointing to it. When the last shared_ptr is destroyed, the resource is deleted and any remaining weak_ptr are set to NULL. One use for weak_ptr, as shown in the example below, is to avoid memory leaks caused by circular references. A weak_ptr can't directly access the resource it points to, we must create a shared_ptr from the weak_ptr to access the resource. There are two ways to do this. • We can pass the weak_ptr to the shared_ptr constructor. That creates a shared_ptr to the resource being pointed to by the weak_ptr and properly increases the reference count. If the resource has already been deleted, the shared_ptr constructor will throw a boost::bad_weak_ptr exception. • We can also call the weak_ptr member function lock(), which returns a shared_ptr to the weak_ptr's resource. If the weak_ptr points to a deleted resource, lock will return an empty shared_ptr. The lock() should be used when an empty shared_ptr isn't considered an error. We can access the resource once you have a shared_ptr to it. This approach is shown in the example below. weak_ptr should be used in any situation where we need to observe the resource but don't want to assume any management responsibilities for it. The example shows the use of weak_ptrs in circularly referential data, a situation in which two objects refer to each other internally. In the example below, we define classes Singer and Song. Each class has a pointer to an instance of the other class. This creates a circular reference between the two classes. Note that we use both weak_ptr and shared_ptr to hold the cross reference to each class.
  • 11. Classes Singer and Song define destructors that each display a message to indicate when an instance of either class is destroyed. Each class also defines a member function to print the title of the Song and Singer's name. Because we can't access the resource directly through a weak_ptr, first we create a shared_ptr from the weak_ptr data member lock(). If the resource the weak_ptr is referencing doesn't exist, the call to the lock() function returns a shared_ptr which points to NULL and the condition fails. Otherwise, the new shared_ptr contains a valid pointer to the weak_ptr's resource, and we can access the resource. If the condition is true (when both songPtr and singerPtr aren't NULL), we print the reference count to show that it increased with the creation of the new shared_ptr, then we print the title of the Song and Singer's name. The shared_ptr is destroyed when the function exits so the reference count decreases by one. Here are the codes: Singer.h #ifndef SINGER_H #define SINGER_H #include <string> using std::string; #include "boost/shared_ptr.hpp" #include "boost/weak_ptr.hpp" class Song; class Singer { public: Singer::Singer(const string &SingerName); ~Singer(); void printSongTitle() ; string name; boost::weak_ptr<Song> weakSongPtr; boost::shared_ptr<Song> sharedSongPtr; }; #endif Song.h #ifndef SONG_H #define SONG_H #include <string> using std::string; #include "boost/shared_ptr.hpp" #include "boost/weak_ptr.hpp" class Singer; // forward declaration class Song { public: Song(const string &SongTitle) ; ~Song();
  • 12. }; #endif void printSingerName(); string title; boost::weak_ptr<Singer> weakSingerPtr; boost::shared_ptr<Singer> sharedSingerPtr; Singer.cpp #include <string> using namespace std; #include "boost/shared_ptr.hpp" #include "boost/weak_ptr.hpp" #include "Song.h" #include "Singer.h" Singer::Singer(const string &SingerName) : name(SingerName) { cout << "Singer constructor: " << name << endl; } Singer::~Singer() { cout << "Singer destructor: " << name << endl; } void Singer::printSongTitle() { // if weaksongPtr.lock() returns a non-empty shared_ptr if (boost::shared_ptr<Song> songPtr = weakSongPtr.lock()) { cout << "Reference count for song " << songPtr->title << " is " << songPtr.use_count() << "." << endl; cout << "Singer " << name << " wrote the song " << songPtr>title << "nn"; } else // weaksongPtr points to NULL cout << "This Singer has no song." << endl; } Song.cpp #include <string> using namespace std; #include "boost/shared_ptr.hpp" #include "boost/weak_ptr.hpp" #include "Song.h" #include "Singer.h" Song::Song(const string &SongTitle) : title(SongTitle) { cout << "Song constructor: " << title << endl; }
  • 13. Song::~Song() { cout << "Song destructor: " << title << endl; } void Song::printSingerName() { // if weakSingerPtr.lock() returns a non-empty shared_ptr if (boost::shared_ptr<Singer> singerPtr = weakSingerPtr.lock() ) { // show the reference count increase and print the Singer's name cout << "Reference count for Singer " << singerPtr->name << " is " << singerPtr.use_count() << "." << endl; cout << "The Song " << title << " was written by " << singerPtr->name << "n" << endl; } else // weakSingerPtr points to NULL cout << "This Song has no Singer." << endl; } main.cpp #include <iostream> #include <string> #include "boost/shared_ptr.hpp" #include "boost/weak_ptr.hpp" #include "Singer.h" #include "Song.h" using namespace std; int main() { cout << "Creating a Song and an Singer ..." << endl; boost::shared_ptr<Song> SongPtr( new Song( "The Boys" ) ); boost::shared_ptr<Singer> SingerPtr(new Singer( "Girls Generation" ) ); cout << "nReferencing the Song and Singer to each other..." << endl; SongPtr->weakSingerPtr = SingerPtr; SingerPtr->weakSongPtr = SongPtr; cout << "nSetting the shared_ptr data members to create the memory leak..." << endl; SongPtr->sharedSingerPtr = SingerPtr; SingerPtr->sharedSongPtr = SongPtr; cout << "Reference count for SongPtr and SingerPtr should be one, but ... " << endl; cout << "Reference count for Song " << SongPtr->title << " is " << SongPtr.use_count() << endl; cout << "Reference count for Singer " << SingerPtr->name << " is " << SingerPtr.use_count() << "n" << endl;
  • 14. cout << "nAccess the Singer's name and the Song's title through " << "weak_ptrs." << endl; SongPtr->printSingerName(); SingerPtr->printSongTitle(); cout << "Reference count for each shared_ptr shoulb be back to one:" << endl; cout << "Reference count for Song " << SongPtr->title << " is " << SongPtr.use_count() << endl; cout << "Reference count for Singer " << SingerPtr->name << " is " << SingerPtr.use_count() << "n" << endl; // the shared_ptrs go out of scope, the Song and Singer are destroyed cout << "The shared_ptrs are going out of scope." << endl; return 0; } In main(), we see the memory leak caused by the circular reference between classes Singer and Song. The lines: boost::shared_ptr<Song> SongPtr( new Song( "The Boys" ) ); boost::shared_ptr<Singer> SingerPtr(new Singer( "Girls Generation" ) ); create shared_ptrs to an instance of each class. The weak_ptr data members are set as: SongPtr->weakSingerPtr = SingerPtr; SingerPtr->weakSongPtr = SongPtr; The shared_ptr data members for each class are set in the lines below. SongPtr->sharedSingerPtr = SingerPtr; SingerPtr->sharedSongPtr = SongPtr; The instances of classes Singer and Song now reference each other. We then print the reference count for the shared_ptr to show that each instance is referenced by two shared_ptrs cout << << cout << << "Reference count for Song " << SongPtr->title << " is " SongPtr.use_count() << endl; "Reference count for Singer " << SingerPtr->name << " is " SingerPtr.use_count() << "n" << endl; the ones we create in the main() and the data member of each instance. Recall that weak_ptr don't affect the reference count. Then we call each class's member function to print the information stored in the weak_ptr data member: SongPtr->printSingerName(); SingerPtr->printSongTitle(); The functions also display the fact that another shared_ptr was created during the function call. Finally, we print the reference counts again to show that the additional shared_ptrs created in the printSingerName and printSongTitle member functions are destroyed when the functions finish. cout << "Reference count for Song " << SongPtr->title << " is " << SongPtr.use_count() << endl;
  • 15. cout << "Reference count for Singer " << SingerPtr->name << " is " << SingerPtr.use_count() << "n" << endl; The output is: Creating a Song and an Singer ... Song constructor: The Boys Singer constructor: Girls Generation Referencing the Song and Singer to each other... Setting the shared_ptr data members to create the memory leak... Reference count for SongPtr and SingerPtr should be one, but ... Reference count for Song The Boys is 2 Reference count for Singer Girls Generation is 2 Access the Singer's name and the Song's title through weak_ptrs. Reference count for Singer Girls Generation is 3. The Song The Boys was written by Girls Generation Reference count for song The Boys is 3. Singer Girls Generation wrote the song The Boys Reference count for each shared_ptr shoulb be back to one: Reference count for Song The Boys is 2 Reference count for Singer Girls Generation is 2 The shared_ptrs are going out of scope. At the end of main(), the shared_ptr to the instances of Singer and Song we created go out of scope and are destroyed. Notice that the output doesn't show the destructors for classes Singer and Song. The program has a memory leak, in other words, the instances of Singer and Song aren't destroyed because of the shared_ptr data members. When songPtr is destroyed at the end of the main(), the reference count for the instance of class Song becomes one because the instance of Singer still has a shared_ptr to the instance of Song, so it's not deleted. When singerPtr goes out of scope and is destroyed, the reference count for the instance of class Singer also becomes one because the instance of Song still has a shared_ptr to the instance of Singer. Neither instance is deleted because the reference count for each is still one. Now, comment out the following lines: //SongPtr->sharedSingerPtr = SingerPtr; //SingerPtr->sharedSongPtr = SongPtr; This prevents the code from setting the shared_ptr data members for classes Singer and Song. Then, we'll have a new output: Creating a Song and an Singer ... Song constructor: The Boys Singer constructor: Girls Generation Referencing the Song and Singer to each other... Setting the shared_ptr data members to create the memory leak... Reference count for SongPtr and SingerPtr should be one, but ... Reference count for Song The Boys is 1
  • 16. Reference count for Singer Girls Generation is 1 Access the Singer's name and the Song's title through weak_ptrs. Reference count for Singer Girls Generation is 2. The Song The Boys was written by Girls Generation Reference count for song The Boys is 2. Singer Girls Generation wrote the song The Boys Reference count for each shared_ptr shoulb be back to one: Reference count for Song The Boys is 1 Reference count for Singer Girls Generation is 1 The shared_ptrs are going out of scope. Singer destructor: Girls Generation Song destructor: The Boys Notice that the initial reference count for each instance is now one instead of two because we don't set the shared_ptr data members. The last two lines of the output show that the instances of classes Singer and Song were destroyed at the end of the main(). We eliminated the memory leak by using the weak_ptr data members rather than the shared_ptr data members. The weak_ptr don't affect the reference count but still allow us to access the resource when we need it by creating a temporary shared_ptr to the resource. When the shared_ptr we created in main() are destroyed, the reference counts become zero and the instances of classes Singer and Song are deleted properly. • intrusive_ptr A pointer that implements reference counting by assuming that the pointed-to object will maintain the reference count itself. Intrusive pointers are useful because they are the same size as the native C++ pointer (no reference-counting mechanism is required), and because they can be constructed directly from native pointers. Properly implementing a smart pointer class can be a daunting task, and all sorts of issues come up, including: • • • • type safety of smart pointers the ability for a smart pointer to be used with an incomplete type correct smart pointer behavior when an exception occurs. runtime costs, which can be high smart pointers - pros and cons This is from Google C++ Style Guide. Smart pointers are objects that act like pointers, but automate management of the underlying memory. If we actually need pointer semantics, scoped_ptr is great. We should only use std::tr1::shared_ptr with a non-const referent when it is truly necessary to share ownership of an object (e.g. inside an STL container). We should never use auto_ptr. • Pros Smart pointers are extremely useful for preventing memory leaks, and are essential for writing exception-safe code. They also formalize and document the ownership of dynamically
  • 17. allocated memory. • Cons We prefer designs in which objects have single, fixed owners. Smart pointers which enable sharing or transfer of ownership can act as a tempting alternative to a careful design of ownership semantics, leading to confusing code and even bugs in which memory is never deleted. The semantics of smart pointers (especially auto_ptr) can be nonobvious and confusing. The exception-safety benefits of smart pointers are not decisive, since we do not allow exceptions. • Decision • scoped_ptr Straightforward and risk-free. Use wherever appropriate. • auto_ptr Confusing and bug-prone ownership-transfer semantics. Do not use. • shared_ptr Safe with const referents (i.e. shared_ptr<const T>). Reference-counted pointers with non-const referents can occasionally be the best design, but try to rewrite with single owners where possible. boost::lambda There are several libraries which are function objects and higher-order programming. They are used as the basis for functionality in TR1. One of those libraries is the Lambda library, which makes it so easy to create function objects on the fly: #include <iostream> #include <vector> #include <algorithm> #include <boost/lambda/lambda.hpp> using namespace std; void makeSquare(vector<int>&v) { for_each(v.begin(), v.end(), cout << boost::lambda::_1*boost::lambda::_1 << " "); } int main() { vector<int> v; for(int i = 1; i <= 10; i++) v.push_back(i); } makeSquare(v); return 0; Output is: 1 4 9 16 25 36 49 64 81 100 For each element x in v, print x*x:
  • 18. boost::lambda::_1*boost::lambda::_1 _1 is the Lambda library's placeholder for the current element. boost::mpl The boost::mpl is a high-level C++ template metaprogramming framework of compile-time algorithms, sequences and metafunctions. Here is an example of calculating a factorial during compilation. It demonstrates looping through recursive template instantiation. It also demonstrates one way in which variables are created and used in template metaprogramming (TMP): #include <iostream> template <int n> struct Factorial { enum { value = n * Factorial<n - 1>::value }; }; template <> struct Factorial<0> { enum { value = 1 }; }; int main() { std::cout << "Factorial<5>::value = " << Factorial<5>::value << std::endl; } The first template is for the general case, and the value of Factorial<n> is n times the value of Factorial<n-1>. The second template is for a special case, which is a template specialization to provide the ending condition for the recursion, and the value of Factorial<0> is 1. Note that it calculates factorials at compile time. However, to be able to use templates in this manner, the compiler must know the value of its parameters at compile time, which has the natural precondition that Factorial<n>::value can only be used if n is known at compile time. In other words, n must be a constant literal or a constant expression. The looping occurs where the template instantiation Factorial<n> references the template instantiation Factorial<n-1>. Each instantiation of the Factorial template is a struct, and each struct uses the enum to declare a template metaprogramming variable named value. This variable value is what holds the current value of the factorial calculation. Since template metaprogramming uses recursive template instantiation in place of loops, each instantiation gets its own copy of value, and each copy has the proper value for its place in the loop. boost::function boost::bind
  • 19. Hash tables Regular expressions - boost::regex • E-mail b[a-zA-Z0-9]+@[a-zA-Z0-9]+.[a-zA-Z]{2,4}b or more general expression b[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}b • ip address to match 999.999.999.999 bd{1,3}.d{1,3}.d{1,3}.d{1,3}b or To restrict all 4 numbers in the IP address to 0..255 b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][09]?). (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][09]?)b Tuples boost::array boost::mem_fn boost::reference_wrapper Random number generation Mathematical special functions C99 compatibility extensions Type traits boost::result_of
  • 20. Boost - pros and cons The followings are from C++ style guide The Boost library collection is a popular collection of peer-reviewed, free, open-source C++ libraries. Use only approved libraries from the Boost library collection. • Pros Boost code is generally very high-quality, is widely portable, and fills many important gaps in the C++ standard library, such as type traits, better binders, and better smart pointers. It also provides an implementation of the TR1 extension to the standard library. • Cons Some Boost libraries encourage coding practices which can hamper readability, such as metaprogramming and other advanced template techniques, and an excessively functional style of programming. • Decision In order to maintain a high level of readability for all contributors who might read and maintain code, we only allow an approved subset of Boost features. Currently, the following libraries are permitted: • Call Traits from boost/call_traits.hpp. • Compressed Pair from boost/compressed_pair.hpp. • Pointer Container from boost/ptr_containerexcept serialization and wrappers for containers not in the C++03 standard (ptr_circular_buffer.hpp and ptr_unordered*). • Array from boost/array.hpp. • The Boost Graph Library (BGL) from boost/graph, except serialization (adj_list_serialize.hpp) and parallel/distributed algorithms and data structures (boost/graph/parallel/* and boost/graph/distributed/*). • Property Map from boost/property_map, except parallel/distributed property maps (boost/property_map/parallel/*). • The part of Iterator that deals with defining iterators: boost/iterator/iterator_adaptor.hpp, boost/iterator/iterator_facade.hpp, and boost/function_output_iterator.hpp.