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.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With