10
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Can’t you use Boost.PP to generate that code for you rather than writing it manually? Additionally: why are the Boost smart pointers unsuitable? \$\endgroup\$ – Konrad Rudolph Jun 8 '13 at 14:42
  • \$\begingroup\$ @KonradRudolph : I did not think about Boost.PP. I'm not even sure I have access to it: When I arrived at my current job, I saw that Boost (in our third-party libraries folder) had been amputated from most of its content. I currently have no choice on that matter. Anyway, the code is automatically generated via script. As for the boost smart pointers, as I explained, I needed a smart pointer which is both lightweight (thus, NOT shared_ptr) and transfer-of-ownerhip-enabled (thus, NOT scopted_ptr). \$\endgroup\$ – paercebal Jun 9 '13 at 15:35
  • \$\begingroup\$ Not sure what you mean by lightweight but I don’t find shared_ptr very heavy at all. The one thing I dislike is the non-configurable thread-safety. \$\endgroup\$ – Konrad Rudolph Jun 9 '13 at 15:53
  • \$\begingroup\$ @KonradRudolph : shared_ptr's problem is its weight (half the time, there will be a separate allocation for the reference counters because the user won't use make_shared, not mentioning the atomic counters) and its semantics (shared ownership, which is not desired in most cases). Herb Sutter has a full discussion on the comparison between shared_ptr and unique_ptr, which IMHO, applies in C++03 with shared_ptr vs. auto_ptr. I updated my question to add the "unique-ownership" need. \$\endgroup\$ – paercebal Jun 10 '13 at 10:12
3
\$\begingroup\$

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).

\$\endgroup\$
  • \$\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 Jun 8 '13 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 Jun 8 '13 at 12:41
  • \$\begingroup\$ Nice links, BTW (STL's proposition, and boost language emulation). I'll read ASAP. \$\endgroup\$ – paercebal Jun 8 '13 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 for T[n] etc. \$\endgroup\$ – TemplateRex Jun 8 '13 at 12:57
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.