Monthly Archives: June 2013

What’s up with TR1? (and C++11, and libc++)

In 2005, the C++ committee issued Technical Report 1 (aka TR1). It added a lot of features to the C++ standard library, mostly taken from boost. Things like shared_ptr, bind, unordered_map, unordered_set, array and lots of other stuff. This was a purely library extension to the standard; no language changes. These extensions were placed into the namespace std::tr1 and the header files were referenced as #include <tr1/xxxx>

Fast forward a couple of years (ok, more than a couple). The C++11 standard was released, and all the stuff (except for some of the esoteric math functions) from TR1 were incorporated into the standard library.

There is no mention of tr1 in the C++11 standard. There is no C++ header named tr1/unordered_map, for example. (There is a header named unordered_map now).

Some standard library vendors have maintained the tr1 header files for backwards compatibility. Other vendors (such as libc++, which being c++11 only, has no backwards compatibility to worry about) do not.

What this means is that part of updating your code to work in C++11, you should probably examine your use of tr1 facilities, and (quite possibly) update them to use the ones in std.

Needless to say, this can cause problems if you want to maintain compatibility with C++03 build systems. You can switch on the version of C++ that you’re building with, and have a using directive to pull the features that you want into either the global namespace or a particular namespace.

#if __cplusplus >= 201103L
#include <memory>
using std::shared_ptr;
#else
#include <tr1/memory>
using std::tr1::shared_ptr;
#endif

Alternately, you can use typedefs

#if __cplusplus >= 201103L
#include <memory>
typedef std::shared_ptr<int> spInt;
#else
#include <tr1/memory>
typedef std::tr1::shared_ptr<int> spInt;
#endif

There is a tool called cpp11-migrate being developed using clang, which helps people migrate their code from c++03 to c++11. Currently, it does things like convert to C++11-style for loops, and finds places where nullptr can be used. It would be really nice if it could also convert uses of std::tr1 facilities to std, but first, someone will have to document what (if any) the differences are between tr1 and C++11’s std. I know there are some; for example, std::tuple does interesting things in C++11 because the language has variadic templates.