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:
- In the code, how should
shared_ptrbe referenced? - Should
std::tr1::shared_ptrbe preferred overboost::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:
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
slistextension 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_cxxnamespace, and we even found one that erroneously put it instd!