Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using boost::shared_ptr with a view to replacing it later

I am working on cross-platform code that needs shared pointers. For reasons beyond my control we cannot use C++11 just yet. So, I have suggested using boost::shared_ptr. When we do adopt C++11 (maybe a year down the line), we should be able to replace boost smart pointers with std smart pointers. My question is about the best way to use boost so that it is easier to switch later. Template aliasing is not available so the following is out:

namespace my {
    template <typename T>
    using shared_ptr = boost::shared_ptr<T>;
}

The other technique of wrapping the shared_ptr inside another struct results in ugly and unreadable APIs as I will then have to use it thus my::shared_ptr<int>::type:

 namespace my  {
     template<typename T>
     struct shared_ptr
     {
          typedef boost::shared_ptr<T> type;
     };
 }

I am looking for alternatives to this. Any suggestions will be appreciated.

EDIT: Another option I considered was this:

namespace my {
     using boost::shared_ptr;
}

And then use my::shared_ptr<int>. Later I would change boost to std in namespace my. However, I am not able to decide on the pro-s and con-s of each of the approaches to reach a decision.

like image 712
341008 Avatar asked Apr 08 '14 06:04

341008


2 Answers

Four options compatible with C++98,

1) use impl::shared_pointer<T>. And switch from:

namespace impl = boost; to namespace impl = std;

2) (more elegant but more risky) is to use shared_ptr without namespace qualification and later switch from

using boost::shared_ptr to using std::shared_ptr.

3) (ugly but I guess is the preferred industrial solution) Use macros all the way.

#if DETECTC++11
#define SHARED_PTR std::shared_ptr
#else
#define SHARED_PTR boost::shared_ptr
#endif

4) Combine the 3 above.

Anonymous namespaces can help to keep the using statements local to a file, so you have per-source-file control, e.g.:

namespace{
  using std::shared_ptr;
}

(I personally use 2. all the time).

like image 101
alfC Avatar answered Oct 12 '22 23:10

alfC


We do something like this in our project:

#if compiler_doesnt_support_c++11
  #include <boost/shared_ptr.hpp>

  namespace std {
    using boost::shared_ptr;
  }
#elif compiler_has_c++11_in_tr1
  #include <memory>
  namespace std {
    using std::tr1::shared_ptr;
  }
#else
  #include <memory>
#endif

And just use std::shared_ptr in the code.

Yes, it's technically Undefined Behaviour (as you're not allowed to add names to the ::std namespace like that), but it has worked without any problems for years.

like image 26
Angew is no longer proud of SO Avatar answered Oct 13 '22 01:10

Angew is no longer proud of SO