What are the best practices for using autoconf
in conjunction
with shared_ptr
and other TR1/BOOST C++0x templates so as to maximize
portability and maintainability?
With autoconf
I can determine whether shared_ptr
is
available as std::tr1::shared_ptr
and/or boost::shared_ptr
. Given
that the same feature has two different names, I have the following
questions:
shared_ptr
be referenced? std::tr1::shared_ptr
be preferred over boost::shared_ptr
?For the first, the code is currently using preprocessor conditionals
allowing non-qualified references to shared_ptr
, a la
#if HAVE_STD_TR1_SHARED_PTR
using std::tr1::shared_ptr;
#elif HAVE_BOOST_SHARED_PTR
using boost::shared_ptr;
#else
#error "No definition for shared_ptr found"
#endif
Second, the code uses std::tr1::
over boost::
to minimize
dependencies on external libraries (even if the the libraries are
widely used).
Are these two solutions common? Are there better ones?
One improvement to your example code, and an answer to your first question, is to use the "template typedef" idiom:
#if HAVE_STD_TR1_SHARED_PTR
template <class T>
struct SharedPtr {
typedef std::tr1::shared_ptr<T> Type;
};
#elif HAVE_BOOST_SHARED_PTR
template <class T>
struct SharedPtr {
typedef boost::shared_ptr<T> Type;
};
#else
# error "No definition for shared_ptr found"
#endif
// Declare a shared_ptr using our wrapper classes, saving us from having to care
// where shared_ptr comes from:
SharedPtr<int>::Type my_shared_int(new int(42));
The main problem with this is the need to use the ::Type notation. It is purely because C++ currently has no way to have a typedef for a template. You can have a typedef for a template type instance, but it's important here that we retain genericity.
As for whether you should prefer TR1 to Boost, I'd say yes. Now that compilers are shipping with partial C++0x support, I'd say you should also test for std::shared_ptr and prefer that to either of the others.
You might need a fourth typedef if there are compilers that have a shared_ptr that's somewhere else. I don't know of such a compiler, but some C++ code I maintain does something similar to what you're asking about with the common slist
extension to the Standard C++ Library, for singly-linked lists. Old g++ versions put it at global namespace, modern g++ puts it in the compiler-specific __gnu_cxx
namespace, and we even found one that erroneously put it in std
!