Beyond the C++ Standard Library

Björn Karlsson

Mentioned 16

Writing for intermediate-to-advanced C++ developers, the author outlines all 58 Boost libraries, and then presents comprehensive coverage of 12 libraries. The topics in this work range from smart pointers and conversions to containers and data structures, explaining exactly how using each library can improve your code.

More on Amazon.com

Mentioned in questions and answers.

This post is about 2 questions in one:

  1. Good books for Boost C++ library
  2. OO Design in C++. I come from Java background and tend to think in terms of Interfaces, Singletons etc. How do I translate it to C++ or how to start thinking differently for C++

-Ajay

Just case on the market:

Introduction to Boost C++ Libraries: Volume 1

Also 2nd volume coming out later this year:

Introduction to Boost C++ Libraries: Volume 2

I've heard a lot of good comments about Boost in the past and thought I would give it a try. So I downloaded all the required packages from the package manager in Ubuntu 9.04. Now I'm having trouble finding out how to actually use the darn libraries.

Does anyone know of a good tutorial on Boost that goes all the way from Hello World to Advanced Topics, and also covers how to compile programs using g++ on ubuntu?

The library documentation is a mixed bag. Some is good, but some is more of a reference than a guide. The best guide to (some of) the Boost libraries is the book Beyond the C++ Standard Library. At the very least, the introduction gives one paragraph descriptions of many of the libraries. From there, you can decide which library is most important for your current needs, and, if it's in the book, read the chapter on it, or read the documentation on the website.

If you read German, there's a good online guide. Google translate does a good enough job that a non-speaker like me can understand it.

Also, unless you have lots of experience with C++, I'd start with the simpler libraries (e.g. smart_ptr, tuple, conversion, tokenizer, regex, date_time, test), before trying the more complicated ones (bind, variant, any), or the really advanced ones (concepts, MPL, Fusion).

I have been learning C++ for three months now and in that time created a number of applications for my company. I consider myself fairly comfortable with C++ / MFC and STL, however I don't just want to be an OK programmer, I want to be a good programmer. I have a few books on best practices but I was wondering if anyone could suggest reading materials that helped them and any disciplines which should be encouraged?

Thanks!

You can check out the Boost library and a number of the books written about it. While this may not have been what you had in mind, IMO, the Boost libraries are examples of well-designed modern C++ libraries that use the features of the language in pretty much the way they should be used to create among the most effective solutions for their problem domain. Granted of course, there are bizarre libraries like preprocessor and MPL which make you wonder if you'll ever have any use for them, but they're all round quite good. From my own experience, exploring the library and its literature has given me insight into how C++ can be used effectively.

Boost Beyond the C++ Standard Library: An Introduction to Boost

For C++, Scott Meyers books are very good, and will help take you to the next level.

If you don't already have it C++ by Bjarne Stroustrup, 3rd Edition

3 months into c++ and you're already comfortable with it? Sheesh, I've been learning c# for over a year and have taken numerous Microsoft courses and I'm nowhere near comfortable with it.

That being said, you'll hear Code Complete tossed about as a very good book. I'm in the process of reading it now.

I lot of folks can suggest more modern, up-to-date books. But I still recommend The Annotated C++ Reference Manual by Margaret A. Ellis & Bjarne Stroustrup.

The ARM was published back in '90. It's become somewhat outdated with respect to templates. STL is (obviously) absent. (Though the website at sgi.com does a good job of covering STL!)

However, the ARM is dirt cheap (used). (Shipping will exceed the cost of the book.) Its signal-to-noise ratio remains off the scale. It's very good at digging into C++'s dirty areas, explaining what was done & why.

I still use it as a reference. I rank it up there with K&R.

Good blogs: Guru of the Week, and all the books by Herb Sutter. Those will give you quite a lot to chew already.

Modern C++ Design by Alexandrescu if you want to get a good feel for what you don't yet know, and probably don't want to know.

Code Kata's for practice!

As I see, nobody mentioned Bruce Eckel brilliant books "Thinking in C++". IMHO, it`s one of the best books to start your C++ development from. From my point of view, first volume is more helpful that the second, but both of them worth reading.
http://www.amazon.com/Thinking-C-Introduction-Standard-One/dp/0139798099/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1227890306&sr=8-1

I recently forced myself to study C++ and I just finished reading the book C++: The Complete Reference, by Herbert Schildt. I liked the book and think I got more or less the big picture. I noticed though that when I try to check with other people the things I code using the material I learned, they are usually considered non-idiomatic and superseded by an STL way to do it that is safer and easier (well, the book doesn't cover STL and Boost libraries).

So I'd like to ask: what are good sources to learn the patterns of a good C++ program? Where can I learn basic patterns from the "C++ way" to do things and not just repeating C patterns in C++?

I'd be particularly interested in sources that included STL and Boost stuff.

I'd (also) recommend:

  • Effective C++, Effective STL by Steve Myers. They are easy to digest, yet very valuable - sometimes even illuminating.
  • Code Complete (The 1993 edition is available cheaply and not that much different). It's lengthy, but it walks across the entire field from what it means to be a programmer to how a for loop should look. (It would be better if it was shorter - the way it is it covers so much ground it's hard to place it). I hold it dear because it illustrate two points very well:
    • code is compromise
    • There are know facts, (but we still manage to get by by gut feel)
  • C++ FAQ Lite / C++ FAQ.
  • I'd throw in Facts and Fallacies by Robert Glass - it doesn't fit your request very well, but go read it.

It's natural that you are unhappy with other people's code. That's typical for programming - heck, even my own code of five years ago was written by a total n00b. That might be more articulated for C++, since it caters for different styles, and often puts freedom ("you can") over guildelines ("that's the way").

Still, mulling over existing code - yours or others - and considering how it can be improved. Also, figuring out why it is the way it is sometimes helps.


(I remember a few TheDailyWTF's where everyone would chime in how stupid and unreasonable this is - yet somewhere, buried among the me too's, was someone with domain experience explaining convincingly under what circumstances this was better than the obvious solution).

You might wnat to check out The Definitive C++ Book Guide and List

For your purposes I would especially recommend:

They are not in particular order, also you might want to read and code something in between them.

(Note: As noted by @John Dibling the Boost book might be a bit out of date, I do not have experience with that one myself)

I'd like to have a good up-to-date reference for boost by my side, and the only books I found are the following:

Both books are somewhat dated, and I am sure boost has been evolving.

Obviously I can just use a direct source of Boost website.

Is it enough to just use the website to learn and reference boost libraries?

What If I am one of those folks who prefers hardcover books? Which one would you recommend?

Thanks

--Edit--

Does anyone know of online video tutorials on Boost, as well as text turials?

I hear a lot about boost here and I am beginning to think it could help a lot with my software development. More so in concurrency and memory management in my particular case as we have had a lot of bugs in this area.

What are the key language features I need to polish up on to effectively benefit from using boost and to shorten the learning curve? I have seen that function objects are commonly used so I would probably need to polish up on that.

Additionally, are there any tutorials and 101 resources I can quickly look at to just get a feel and understanding on using boost.

I realise there is a lot boost offers and I have to pick the right tools for the right job but any leads will help.

Related

Try Björn Karlsson's book: Beyond the C++ Standard Library: An Introduction to Boost. Its pretty straightforward and easy to grasp. I read this after I'd finished Scott Meyers three c++ books (effective series).

After reading Beyond the C++ Standard Library: An Introduction to Boost, I would recommend casually browsing the documentation on boost.org, just to get an idea of what's available. You can do a deep dive into a specific boost library when it looks like a good fit for a particular application.

Code snippet from lexical_cast:

class lexical_castable {
public:
  lexical_castable() {};
  lexical_castable(const std::string s) : s_(s) {};

  friend std::ostream operator<<
    (std::ostream& o, const lexical_castable& le);
  friend std::istream operator>>
    (std::istream& i, lexical_castable& le);

private:
  virtual void print_(std::ostream& o) const {
    o << s_ <<"\n";
  }

  virtual void read_(std::istream& i) const {
    i >> s_;
  }

  std::string s_;
};

std::ostream operator<<(std::ostream& o,
  const lexical_castable& le) {
  le.print_(o);
  return o;
}

std::istream operator>>(std::istream& i, lexical_castable& le) {
  le.read_(i);
  return i;
}

Based on document,

template<typename Target, typename Source>
  Target lexical_cast(const Source& arg);

1> Returns the result of streaming arg into a standard library string-based stream and then out as a Target object.

2> Source is OutputStreamable

3> Target is InputStreamable

Question1> For User Defined Type (UDT), should the OutputStreamable or InputStreamable always have to deal with std::string? For example, given a class containing a simple integer as member variable, when we define the operator<< and operator>>, what is the implementation code looks like? Do I have to convert the integer as a string? Based on my understanding, it seems that UDT always has to deal with std::string in order to work with boost::lexical_cast and boost::lexcial_cast needs the intermediate std::string to do the real conversion jobs.

Question2> Why the return value of operator<< or operator>> in above code is not reference to std::ostream& or std::istream& respectively?

I just had a hell of a project doing simple operations on C++, then when I was almost completely done with the project I found out that all this stupid tasks required just a portion of boost. This was quite frustrating and let me wondering how many of these annoying problems could be solved with a single function of the boost libraries.

So the question is, is there any cheat sheet for the boost libraries? I mean, that I can say right away, I should look at this part of boost to solve the problem. Most of the times the description that appear in the main page of boost doesn't even explain what it is intented or, specially for somebody whose not use to all these C++ specific words.

I personally find the Boost Libraries page to be much easier to navigate than the main page of Boost.

That Boost Libraries page is the closest I'm aware of to a cheat sheet. Other than that, all I can recommend is to periodically browse the Boost docs as you start work on new areas of your project; libraries that you previously saw little need for will start to make sense as you see how to apply their functionality to your project and as you learn more of C++ to see how C++-specific features like type traits can benefit you.

You might also try Beyond the C++ Standard Library: An Introduction to Boost. I've not read it.

I am a seasoned .NET and C++ programmer who has been almost exclusively programming in C# for last 5 years and now I had to go "back" to start programming in C++ again.

Before becoming a C# developer I was a hardcore C++/STL/COM programmer, but never really used Boost back then (apart from playing around with a smart pointers from Boost).

I am sort of refreshed my memory of C++ to a working level and now keen to learn Boost again. Can someone recommend me a quick way to learn Boost to a reasonable (ok, let me face it, newbie) working level. Any Boost FAQ, learning resourses, ideas and suggestions would be greatly appreciated.

I can't see any reason to learn whole Boost at once. You could reference to Boost Documentation for information about parts of Boost you really need in your work.

There is a book - Beyond the C++ Standard Library: An Introduction to Boost. You could start from reading it.

Based on pp. 8

Free Functions

template<typename T> void swap(scoped_ptr<T>& a,scoped_ptr<T>& b)

This function offers the preferred means by which to exchange the contents of two scoped pointers. It is preferable because swap(scoped1,scoped2) can be applied generically (in templated code) to many pointer types, including raw pointers and third-party smart pointers.[2] scoped1.swap(scoped2) only works on smart pointers, not on raw pointers, and only on those that define the operation.

int* pA = new int(10);
int *pB = new int(20);

boost::swap(pA, pB); // Error: could not deduce template argument for 'boost::scoped_ptr<T> &' from 'int *'

Question> How to swap raw pointers with boost::swap?

I don't understand why the other answers are telling you not to use boost::swap. The entire purpose of boost::swap is to hide the using std::swap; swap(x, y); business. This works just fine:

#include <boost/swap.hpp>

int main()
{
    int* pA = new int(10);
    int *pB = new int(20);

    boost::swap(pA, pB);

    delete pA;
    delete pB;
}

Obviously if you haven't included boost/swap.hpp this won't work. That's how you use boost::swap to swap two things. You should always prefer to swap two things in this form!

What you're reading is simply stating that boost::scoped_ptr also provides an overload of swap inside the boost namespace, so that this works too:

#include <boost/scoped_ptr.hpp>

int main()
{    
    boost::scoped_ptr<int> pA(new int(20));
    boost::scoped_ptr<int> pB(new int(20));

    boost::swap(pA, pB);
}

But it should be clear that this won't work:

#include <boost/scoped_ptr.hpp>

int main()
{
    int* pA = new int(10);
    int *pB = new int(20);

    boost::swap(pA, pB);

    delete pA;
    delete pB;
}

Because boost/scoped_ptr.hpp has not provided (and indeed doesn't have the responsibility to provide) a general implementation of boost::swap. If you want to use boost::swap in general, you must include boost/swap.hpp:

#include <boost/scoped_ptr.hpp>
#include <boost/swap.hpp>

int main()
{
    int* pA = new int(10);
    int *pB = new int(20);

    boost::scoped_ptr<int> pC(new int(20));
    boost::scoped_ptr<int> pD(new int(20));

    boost::swap(pA, pB);
    boost::swap(pC, pD);

    delete pA;
    delete pB;
}

Like that. If you have Boost available to do, do not fall back to the using std::swap stuff.

Based on the book, pp338

#include <iostream>
#include <vector>
#include <string>
#include <ostream>
#include <algorithm>

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/cast.hpp>

using namespace std;

template <typename R, typename Arg> class invoker_base {
public:
  virtual R operator()(Arg arg)=0;
};

template <typename R, typename Arg> class function_ptr_invoker 
  : public invoker_base<R,Arg> {
  R (*func_)(Arg);
public:
  function_ptr_invoker(R (*func)(Arg)):func_(func) {}

  R operator()(Arg arg) {
    return (func_)(arg);
  }
};

template <typename R, typename Arg> class function1 {
  invoker_base<R,Arg>* invoker_;
public:
  function1(R (*func)(Arg)) : 
    invoker_(new function_ptr_invoker<R,Arg>(func)) {}

  R operator()(Arg arg) {
    return (*invoker_)(arg);
  }

  ~function1() {
    delete invoker_;
  }
};

bool some_function(const std::string& s) {
  std::cout << s << " This is really neat\n";
  return true;
}

int main() {
  function1<bool,const std::string&> f1(&some_function);
  f1(std::string("Hello"));
}

Question> the default destructor of invoker_base is NOT virtual. Does there exist memory leak in the implementation of function1? As the code indicates, the function1::~function1 deletes the allocated resource through a non-virtual base class pointer.

There is no memory-leak here (the object doesn't own any resource that needs delete-ing).

However, invoking delete on a non-base object through a pointer-to-base without a virtual destructor causes undefined behaviour.

Am struggling a lot to find how to do to use boost::any to create a print function that can print any type using template first.

template <typename T>
struct printer {
    void print(ostream& os, const boost::any& a);
}; 

I need to define first print(). i wish to have the real operator << for any, The idea is simple: attach to each any object an instance of class printer<T> with the suitable T and change this object when the value type of the any changes. A first technical problem is that the printer object depends on T whereas any is not (and should not be) a class template.

Please I really need a hand is for tonight or tomorrow I have a deadline for tomorrow but I wish to work on it tonight.

There is quite easy way to do this, described in "Beyond the C++ Standard Library: An Introduction to Boost":

struct streamer {
  virtual void print(ostream &o, const boost::any &a) const =0;
  virtual streamer * clone() const = 0;
  virtual ~streamer() {}
};

template <class T>
struct streamer_impl: streamer{
  void print(ostream &o, const boost::any &a) const { o << *boost::any_cast<T>(a); }
  streamer *clone() const { return new streamer_impl<T>(); }
};

class any_out {
  streamer *streamer_;
  boost::any o_;
  void swap(any_out & r){
    std::swap(streamer_, r.streamer_);
    std::swap(o_, r.o_);
  }
public:
  any_out(): streamer_(0) {}
  template<class T> any_out(const T& value)
    : streamer_(new streamer_impl<T>()), o_(value) {}
  any_out(const any_out& a)
    : streamer_(a.streamer_ ? a.streamer_->clone() : 0), o_(a.o_) {}

  template <class T>
  any_out & operator=(const T& r) { 
    any_out(r).swap(*this);
    return *this;
  }
  ~any_out() { delete streamer_; }

  friend std::ostream &operator<<(std::ostream& o, const any_out & a) {
    if(a.streamer_)
      a.streamer_->print(o, a);
    return o;
  }
};

and then you use any_out instead of boost::any.

I have been developing using c# now since the first release of .NET. I have never really spent time on C or C++ and thought it would be a good idea to get a little more awareness. Does anyone have any recommendations for sites that would provide a good learning/tutorial for someone that has c# experience to venture into C++ a little?

Thanks

Warning: C++ is not C and the following is related only with C++.

If you are already a c# developer I think you should work in three different directions:

1) copy semantic, memory management and const keyword, these are the main differences between c# and c++. Make yourself familiar with copy constructor, destructor and assignment operator. Learn how to use RAII idiom. Study the differences between passing a variable by: value, reference and pointer.

I will suggest Effective C++ http://www.amazon.com/Effective-Specific-Improve-Programs-Designs/dp/0321334876 also guru of the week it is a great source.

In More Effective C++ there is a nice chapter on the difference between pointer and reference.

2) you need to make yourself familiar with the standard library, in my opinion this is a really good book http://www.amazon.co.uk/Standard-Library-Tutorial-Reference/dp/0201379260/ref=sr_1_4?ie=UTF8&qid=1314957062&sr=8-4

3) the standard library is great but not enough, you will soon need boost.

I am reading this book at the moment http://www.amazon.co.uk/Beyond-Standard-Library-Introduction-Boost/dp/0321133544/ref=sr_1_1?ie=UTF8&qid=1314957541&sr=8-1

I haven't finished it yet, but it looks good so far.

Keep practise, you are going to love coding in c++.

Based on pp130

However, it would be nice to also have a version that supports comparisons between T and compatible types, which is simply a case of adding more overloads. For symmetry, you need to allow either type to be on the left side of the operation. (This is easy to forget when adding operators manually; one tends to only see clearly the fact that the right side must accept the other type. Of course, your two-type version of less_than wouldn't make such silly mistakes, right?)

template <class T,class U>
class less_than2
{
public:
  friend bool operator<=(const T& lhs,const U& rhs) { 
    return !(lhs>rhs); 
  }

  friend bool operator>=(const T& lhs,const U& rhs) { 
    return !(lhs<rhs); 
  }

  friend bool operator>(const U& lhs,const T& rhs) {
    return rhs<lhs; 
  }

  friend bool operator<(const U& lhs,const T& rhs)  { 
    return rhs>lhs; 
  }

  friend bool operator<=(const U& lhs,const T& rhs) { 
    return !(rhs<lhs); 
  }

  friend bool operator>=(const U& lhs,const T& rhs) { 
    return !(rhs>lhs); 
  }
};

Question> Why we don't have to provide the following two functions?

  friend bool operator>(const T& lhs,const U& rhs) {
    return rhs<lhs; 
  }

  friend bool operator<(const T& lhs,const U& rhs)  { 
    return rhs>lhs; 
  }

Based on Beyond the C++ Standard Library: An Introduction to Boost, section Using Boost.Bind with Boost.Function on page 328, the author illustrates one of the way that we can decouple the calling code from underlying implementation code.

When separating graphical user interfaces (GUIs) from details on how to handle actions (events) from the user, callbacks of some sort are almost always used. If this callback mechanism is based on function pointers, it is hard to avoid severe limitations of the types that can be used with the callback, which in turn increases the risk of adding coupling between the presentation and the business logic. We can avoid this altogether by using Boost.Function, and when combined with a library that supports argument binding, we can supply the context to invocations of functions with ease. This is one of the most common uses of this libraryto separate knowledge of the business logic from the presentation layer.

class tape_recorder {
public:
  void play() {
    std::cout << "Since my baby left me...\n";
  }

  void stop() {
    std::cout << "OK, taking a break\n";
  }

  void forward() {
    std::cout << "whizzz\n";
  }

  void rewind() {
    std::cout << "zzzihw\n";
  }

  void record(const std::string& sound) {
    std::cout << "Recorded: " << sound << '\n';
  }
};

typedef boost::function<void()> command;

tape_recorder tr;

command play(boost::bind(&tape_recorder::play,&tr));
command stop(boost::bind(&tape_recorder::stop,&tr));
command forward(boost::bind(&tape_recorder::stop,&tr));
command rewind(boost::bind(&tape_recorder::rewind,&tr));
std::string s="What a beautiful morning...";
command record = boost::bind(&tape_recorder::record,&tr,s));


// Invoked from some GUI control...
  if (play) {
    play.execute();
  }

  // Invoked from some scripting client...
  stop.execute();

With Boost.Function and Boost.Bind, it is possible to achieve the decoupling that makes it possible for the invoking code to know nothing about the code being invoked. It's immensely useful to combine these two libraries in this way.

Question> I understand how the above code works but I still feel confused how to decouple the calling code from the real implementation as what the author originally wants to archive. The calling code(i.e. all kinds of commands) still needs to know what the member functions of tape_recorder. So what the decoupling really mean here?