Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I maintain a project that compiles as both C++11 and C++03. One pain point is that the headers have changed between them: #include <tr1/memory> to #include <memory>. This is complicated further by libc++, which doesn't have <tr1/memory>.


That's fairly straightforward to work around, however.

I've used both autoconf and cmake to do functional testing of which headers are available, and then include the most recent available out of <memory>, <tr1/memory> and <boost/shared_ptr.hpp>, bringing them into a project::compat namespace to make the codebase not need to care which is in use, and the same for a number of other tr1/boost types now in C++11/14.

I'm now at the point where for some projects I've been able to strip out this entirely and just use the C++11 types directly.


That is relatively straightforward in the scope of a large project (and it's what I do as well), but stuff like this really makes it harder to share small-to-medium sized C++ libraries.

I don't understand why C++03 didn't just use the std:: namespace.


What about a preprocessor check based on the __cplusplus value? If it's 199711L, implement the C++03 defines, if not, implement the C++11 defines.


Unfortunately this doesn't handle the libc++ case, which needs #include <memory> even in C++03.

What I ended up doing is something like this:

    // Ensure that _LIBCPP_VERSION is defined if necessary
    #include <ciso646>

    #if defined(_LIBCPP_VERSION) || __cplusplus > 199711L
      // C++11 or libc++
      #include <memory>
      using std::shared_ptr;
    #else
     // C++03 or libstdc++
     #include <tr1/memory>
     using std::tr1::shared_ptr;
    #endif


A quick Google search suggests that this won't work unless you also check for the MSVC version - sigh:

http://stackoverflow.com/questions/14131454/visual-studio-20...


If we changed __cplusplus before implementing every single C++11 feature, the Internet would riot.


If you're exposing __cplusplus=199711L then you really ought to continue to support #include <tr1/memory> (i.e. C++03 style). As long as you do that there's no problem and the suggested thing should work.


VC++ never used <tr1/memory> in the first place. That was purely a libstdc++ thing, and not something that TR1 or any C++ standard ever said to do.


Yep. (TR1 was published after C++03, they're totally different things.) What we did with TR1 was actually very friendly to migration - we provided std::tr1::meow in <meow> (in 2008 SP1), then in 2010 we aliased that to std::meow as C++0x was being finalized, then in 2012 we switched the True Name to std::meow and made std::tr1::meow the alias for back-compat. At some point in the future we'll probably remove the tr1 aliases completely.

For the Technical Specifications, we're following their header directory and namespace rules (<experimental/meow>).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: