I want to provide, in the the spirit of C++11/boost make_shared and C++14 make_unique, a production-ready make_auto for C++03 compilers.
So, inspired boost's make_shared implementation for C++03 compilers, I provide N overloads (0 to 10, currently) of the same make_auto function.
template <typename T>
inline std::auto_ptr<T> make_auto()
{
return std::auto_ptr<T>(new T()) ;
}
template <typename T, typename T_0>
inline std::auto_ptr<T> make_auto(const T_0 & p_0)
{
return std::auto_ptr<T>(new T(p_0)) ;
}
template <typename T, typename T_0, typename T_1>
inline std::auto_ptr<T> make_auto(const T_0 & p_0, const T_1 & p_1)
{
return std::auto_ptr<T>(new T(p_0, p_1)) ;
}
// etc.
Is there something wrong with this code?
Implementation details:
- the const reference is inspired by boost's shared_ptr. After trying multiple alternatives (including GManNickG's excellent answer here), I had to gave up because of some challenged compilers. To pass non-const references, I'll use boost::ref.
- the
inline
keyword is mandatory for reasons that have nothing to do with the problem.
Background info:
I need this for multiple reasons, among them:
- I am stuck with C++03 compilers (and I suspect some of them of not even being that... I'm looking at you, SunStudio). This means even C++03 emulations of unique_ptr don't work (we tried)
- avoiding writing new/delete in my C++ code (see Stroustrup's C++11 style video)
- offering my coworkers the means to use a more modern C++ coding style despite aforementioned compilers limitations (RAII, that is)
- more exception safety
- I need a lightweight smart pointer with unique-ownership semantics, able to transfer ownership, so boost::shared_ptr and boost::scoped_ptr are not an option
2 Answers 2
Disclaimer: this is not an attempt to answer your technical question, but suggesting alternatives to reach some compromise of your stated goals. It wouldn't fit in a comment :-)
I am not sure it is a good idea to actually write a make_auto
. It is akin to rearranging the deck chairs on the Titanic. After it hit the iceberg.
You'd be better off with emulating a std::unique_ptr
using C++98/03 features. Howard Hinnant has one version on his website. You might even get lucky and get its macro variadic version to work nicely with the std::make_unique
proposal by Stephan T. Lavavej.
I'd take that as the preferred option, with using boost::shared_ptr
or boost_scoped_ptr
as the preferred alternative option. If you insist on keeping std::auto_ptr
, make its use as painful as possible. Without pain, you'll find it more difficult to convince your colleagues to upgrade to C++11.
Please also make sure to introduce your team to the other language emulation features that Boost provides (Foreach, Move).
-
\$\begingroup\$ We tried Howard Hinnant's approach, both the version from Boost and the one from on his website. The problem is that some of our mentally-challenged C++ compilers didn't compile it. . . As for convincing colleagues, it's more like convincing customers, and that path is definitively closed: We will upgrade the compilers according to the platform evolution, nothing more. \$\endgroup\$paercebal– paercebal2013年06月08日 12:38:32 +00:00Commented Jun 8, 2013 at 12:38
-
\$\begingroup\$ Thus: 1. We need auto_ptr because it's cheaper and more correct in single-ownership semantics than shared_ptr, it has transfer of ownership semantics, which scoped_ptr does not, and is more or less supported on our compilers, which is not the case for unique_ptr. . . 2. As the rationale for make_auto, it is to avoid naked new calls (search for Stroustrup's abundant comments on that) . . . believe me: Using current alternative on my day job is my fondest professional dream... but it is still a dream, and I must cope with the reality, and thus teach colleagues how to use correctly auto_ptr. \$\endgroup\$paercebal– paercebal2013年06月08日 12:41:30 +00:00Commented Jun 8, 2013 at 12:41
-
\$\begingroup\$ Nice links, BTW (STL's proposition, and boost language emulation). I'll read ASAP. \$\endgroup\$paercebal– paercebal2013年06月08日 12:47:43 +00:00Commented Jun 8, 2013 at 12:47
-
1\$\begingroup\$ @paercebal OK, I understand your position. Good luck with your implementation. I think the
make_unique
proposal is "simple" enough to try to mimic, if at least you drop the overloads forT[n]
etc. \$\endgroup\$TemplateRex– TemplateRex2013年06月08日 12:57:45 +00:00Commented Jun 8, 2013 at 12:57
I think it's OK.
You could try providing both const and non-const references version if you need non-const references for dependency injection.
Boost.PP would help with the boilerplate. Amputated boost is usually selected parts imported using the bcp
tool that comes with Boost. Usually that's done simply to limit the size of the working directory. So it should be possible to import more of it, test that it works with all compilers you have to support and go with it.
shared_ptr
very heavy at all. The one thing I dislike is the non-configurable thread-safety. \$\endgroup\$