C++17, deprecated functions in <memory> standard library? - c++

I am just realizing that some functions of the Dynamic memory management standard library have been deprecated in C++17. An example is get_temporary_buffer:
template< class T >
std::pair< T*, std::ptrdiff_t > get_temporary_buffer( std::ptrdiff_t count );
Can somebody explain why? Can I expect there to be an alternative in C++20?

According to the proposal that deprecates it:
This API would be considered an incomplete thought were it proposed today. As a functional API it lacks exception safety if the function allocating the buffer leaks, yet we offer no RAII-like wrappers to promote safe use.
It has been suggested that all current implementation of this API actually do not perform a more efficient allocation than the regular new operator, and, if that is genuinely the case, we should seriously consider deprecating this facility. Otherwise, we should probably complete the design with an appropriate guard/wrapper class, and encourage vendors to deliver on missed optimization opportunities.
In short, just use new/delete. Or your own temporary memory allocator; whichever works best for your needs.

Related

How can I construct my objects allocated through std::allocator::allocate()?

C++20 removed the construct() and destruct() members from std::allocator. How am I supposed to construct my objects allocated through std::allocator<T>::allocate()? I found std::uninitialized_fill() and std::uninitialized_copy(), but as far as I understood they are not allocator-aware, and they do copies, which I think would hurt performance a lot for non-POD types.
You can do it using std::allocator_traits.
The point of removing the construct method is because the allocator traits already has that method, and the STL containers use std::allocator_traits::construct anyway.
Documentation in cppreference
And here is a little example: (Alloc is any allocator)
Alloc a{};
std::allocator_traits<Alloc>::pointer i = std::allocator_traits<Alloc>::allocate(a, allocated_size);
// You use the construct and destroy methods from the allocator traits
std::allocator_traits<Alloc>::construct(a, i, value_to_construt);
std::allocator_traits<Alloc>::destroy(a, i);
std::allocator_traits<Alloc>::deallocate(a, i, allocated_size);
It looks like a static form of construct still exists in C++20. Maybe that is intended to replace the original form of construct?
https://en.cppreference.com/w/cpp/memory/allocator_traits/construct
I have not really done much with custom allocation so I don't have personal experience using these functions, but it seems reasonable that they might prefer a static function in an effort to break dependencies.
There is also a construct_at function that is added with C++20.
https://en.cppreference.com/w/cpp/memory/construct_at

What are the differences between std::variant and boost::variant?

In an answer to this SO question:
What is the equivalent of boost::variant in the C++ standard library?
it is mentioned that boost::variant and std::variant differ somewhat.
What are the differences, as far as someone using these classes is concerned?
What motivation did the committee express to adopt std::variant with these differences?
What should I watch out for when coding with either of these, to maintain maximum compatibility with switching to the other one?
(the motivation is using boost::variant in pre-C++17 code)
Assignment/emplacement behavior:
boost::variant may allocate memory when performing assignment into a live variant. There are a number of rules that govern when this can happen, so whether a boost::variant will allocate memory depends on the Ts it is instantiated with.
std::variant will never dynamically allocate memory. However, as a concession to the complex rules of C++ objects, if an assignment/emplacement throws, then the variant may enter the "valueless_by_exception" state. In this state, the variant cannot be visited, nor will any of the other functions for accessing a specific member work.
You can only enter this state if assignment/emplacement throws.
Boost.Variant includes recursive_variant, which allows a variant to contain itself. They're essentially special wrappers around a pointer to a boost::variant, but they are tied into the visitation machinery.
std::variant has no such helper type.
std::variant offers more use of post-C++11 features. For example:
It forwards the noexcept status of the special member functions of its constituent types.
It has variadic template-based in-place constructors and emplacement functions.
Defect resolutions applied to C++17 may mean that it will also forward trivial copyability of its types. That is, if all of the types are trivially copyable, then so too will variant<Ts>.
It seems the main point of contention regarding the design of a variant class has been what should happen when an assignment to the variant, which should upon completion destory the old value, throws an exception:
variant<std::string, MyClassWithThrowingDefaultCtor> v = "ABC";
v = MyClassWithThrowingDefaultCtor();
The options seem to be:
Prevent this by restricting the possible representable types to nothrow-move-constructible ones.
Keep the old value - but this requires double-buffers.
Construct the new value on the heap, store a pointer to it in the variant (so the variant itself is not garbled even on exception). This is, apparently, what boost::variant does.
Have a 'disengaged' state with no value for each variant, and go to that state on such failures.
Undefined behavior
Make the variant throw when trying to read its value after something like that happens
and if I'm not mistaken, the latter is what's been accepted.
This is summarized from the ISO C++ blog post by Axel Naumann from Nov 2015.
std::variant differs slightly from the boost::variant
std::variant is declared in the header file rather than in <boost.variant.hpp>
std::variant never ever allocates memory
std::variant is usable with constexpr
Instead of writing boost::get(&variable), you have to write std::get_if(&variable) for std::variant
std::variant can not recursively hold itself and misses some other advanced techniques
std::variant can in-place construct objects
std::variant has index() instead of which()

Letting go of auto_ptr

Occasionally, for fleeting moments, I think auto_ptr is cool. But most of the time I recognize that there are much simpler techniques that make it irrelevant. For example, if I want to have an object freed automatically, even if an exception is thrown, I could new up the object and assign to an auto_ptr. Very cool! But I could have more easily created my object as a local variable, and let the stack take care of it (duh!).
Thus I was not too surprised when I found google C++ coding standards banning the use of auto_ptr. Google states that scoped_ptr should be used instead (if a smart pointer is needed).
I'd like to know if anyone, contrary to my experience, can give a solid reason(s) of when auto_ptr is the best or simplest thing to use. If not, then I suppose I will ban using it myself (following google's lead).
update: For those who expressed concern, no I am not adopting google standards. For example, against google advice, I agree exception-handling should be activated. I also like using preprocessor macros, such as the printable enum I made. It is just the auto_ptr topic that struck me.
update2: It turns out my answer comes from two of the responders below, and a note from Wikipedia. First, Herb Sutter did show a valid use (source-sink idiom and lifetime-linked object composition). Second, there are shops where TR1 and boost are not available or banned and only C++03 is allowed. Third, according to Wikipedia, the C++0x spec is deprecating auto_ptr and replacing it with unique_ptr. So my answer is: use unique_ptr if available to me (on all platforms in consideration) else use auto_ptr for the cases that Sutter depicts.
It's the simplest thing to use when you need a scoped or unique pointer and you are working in a strict C++03 environment with no access to a tr1 implementation or boost.
Herb Sutter can help you out on this one: http://www.drdobbs.com/184403837
While banning auto_ptr seems attractive, but there is one issue:
template <typename T>
some_smart_ptr<T> create();
What will you replace the some_smart_ptr placeholder with ?
The generic answer, shared_ptr, is only worth it if the ownership is truly shared, if the function grants the caller exclusive ownership of the resources, it's misleading at best (and a typical case of premature pessimization as far as I am concerned).
On the other hand, in C++03, no other form of smart pointer can deliver: it's impossible, without move semantics, to provide what we'd like here. auto_ptr or a naked pointer are the two logical contenders. But then a naked pointer exposes you to the risk of leaks if the caller is careless.
With C++0x, unique_ptr advantageously replace auto_ptr in every situation.
std::auto_ptr still has pointer semantics, so automatic (non-pointer) variables aren't a substitute. In particular, std::auto_ptr supports polymorphism and re-assignment. With stack variables you can use references for polymorphism, but references don't allow for re-assignment.
Sometimes std::auto_ptr will do just fine. For example, for implementing a pimpl. True, in the vast majority of cases boost' smart pointer library offers better choices for a smart pointer. But right now std::auto_ptr is a standard solution, whereas boost's smart pointers aren't.
Using auto_ptr as function return value you will enjoy no copiyng overhead and never have memory leak. std::auto_ptr<obj> foo() can be safely called in { foo(); } while obj *foo() cannot. boost::shared_ptr can solve this, but with higher overhead.
Also, some objects can't be created on stack because of memory constraints: thread stacks are relatively small. But boost::scoped_ptr is better in this case since it can't be accidentally released.
Well one reason would be that scoped_ptr is non-copyable, so it's safer to use and harder to make mistakes with. auto_ptr allows transfer of ownership (eg. by passing it another auto_ptr as a constructor parameter). If you need to think things like transferring the ownership, the chances are you're better off with a smart pointer like shared_ptr.

Is auto_ptr deprecated?

Will auto_ptr be deprecated in incoming C++ standard?
Should unique_ptr be used for ownership transfer instead of shared_ptr?
If unique_ptr is not in the standard, then do I need to use shared_ptr instead?
UPDATE: This answer was written in 2010 and as anticipated std::auto_ptr has been deprecated. The advice is entirely valid.
In C++0x std::auto_ptr will be deprecated in favor of std::unique_ptr. The choice of smart pointer will depend on your use case and your requirements, with std::unique_ptr with move semantics for single ownership that can be used inside containers (using move semantics) and std::shared_ptr when ownership is shared.
You should try to use the smart pointer that best fits the situation, choosing the correct pointer type provides other programmers with insight into your design.
Yes, as of today auto_ptr will be deprecated in C++0x and you should use unique_ptr instead. From the latest draft standard (n3035), section D.9
The class template auto_ptr is deprecated. [ Note: The class template unique_ptr (20.9.10) provides a better solution. —end note ]
Until the standard is ratified, it's always possible that the committee will revise this decision although I feel that is unlikely for this decision.
Not only auto_ptr is deprecated in C++11 (D.10, page 1228), it will also be deleted in a future version of C++:
Adopted N4190, and actually removed (not just deprecated) several archaic things from the C++ standard library, including auto_ptr, bind1st/bind2nd, ptr_fun/mem_fun/mem_fun_ref, random_shuffle, and a few more. Those are now all removed from the draft C++17 standard library and will not be part of future portable C++.
Another document about it: Programming Language C++, Library Evolution Working Group - Document N4190, if you want more information.
You can convert any code using auto_ptr automaticaly, by using unique_ptr instead:
Any code using auto_ptr can be mechanically converted to using unique_ptr, with move() inserted whenever auto_ptr was being "copied".
No, it isn't deprecated. It may be, if C++0x ever gets accepted. And it will realistically always be supported. I don't believe that any deprecated feature has ever been dropped from real-world C++ implementations.

Passing object ownership in C++

What is the best way to indicate that an object wants to take ownership of another object? So far, I've been using a std::auto_ptr in the public interface, so the client knows that the interface wants to take ownership of the passed object.
However, the latest GCC tells me auto_ptr is deprecated, so I wonder what is recommended? boost::interprocess::unique_pointer looks like a good candidate, but is this really the best solution out there?
boost::interprocess is a library for interprocess communication, so I wouldn't use it for different purposes.
As discussed on this forum:
http://objectmix.com/c/113487-std-auto_ptr-deprecated.html
std::auto_ptr will be declared deprecated in the next version of the standard, where it will be recommended the usage of std::unique_ptr, which requires rvalue references and move semantics to be implemented (that's a fairly complicated feature).
Until the new standard is released, I would simply try to disable the warning if possible, or ignore it, for maximum portability.
If you want to already switch to the next language standard, it is possible since rvalue references have been implemented (see http://russ.yanofsky.org/rref/), so also std::unique_ptr should be supported.
On of the advantages of the new semantics is that you can pass to the move constructor also a temporary or any rvalue; in other cases, this allows avoiding to copy (for instance) objects contained inside a std::vector (during reallocation) before destroying the original ones.
std::unique_ptr is indeed the new recommended way. With C++0x containers will become move-aware, meaning that they can handle types which are movable correctly (i.e., std::vector<std::auto_ptr<x> > does not work, but std::vector<std::unique_ptr<x>> will).
For boost, the boost::interprocess containers already support movable types, where boost::interprocess::unique_ptr is one of them. They resemble movable types in pre C++0x by using some of the "normal" boost-template wizardry, and use r-value references where they are supported.
I didn't know about the auto_ptr dedicated deprecation, though, but I've not followed the new standard evolution closely.
(edit) The implementation of boost::interprocess::unique_ptr is indeed not a "public" smart-pointer like boost::shared_ptr or boost::scoped_ptr, but it is (see boost.interprocess's site) not just for shared-memory, but can also be used for general-purpose.
However, I'm quite sure that if GCC deprecates the auto_ptr template, they already provide their own unique_ptr implementation (not much use to deprecate if you not have a viable alternative yet).
However, that all being said, if you're working on a C++0x platform, use unique_ptr, available from the compiler's lib, if not, stick with auto_ptr.
I agree where possible you should use types where the compiler assists in ownership transfer.
Where you don't have that choice of data types and are passing raw pointers, I follow the Taligent programming guidelines of naming methods which relinquish ownership as orphanBlah and parameters which take ownership as adoptBlah.
std::auto_ptr implements ownership passing on copy and assignment, so there is nothing special you should do about it:
std::auto_ptr< T > p = somePtr; // not p owns object, referenced by somePtr
std::auto_ptr< T > q = myObj.GetAutoPtr(); // not q owns object referenced by auto_ptr in myObj
But passing object ownership is not a good design practice, it conducts to leaks and object lifetime relative errors.
I don't remember std::auto_ptr being deprecated.
Anybody have a link to the appropriate standards meeting where they discuss this?
A quick google found this:
http://objectmix.com/c/113487-std-auto_ptr-deprecated.html
>> In fact the latest publicly available draft lists auto_ptr in appendix
>> D, meaning that there is clear intent to formally deprecate it in the
>> next revision of C++. A new class named unique_ptr is going to provide
>> a replacement for auto_ptr, the main difference being that unique_ptr
>> uses rvalue-references instead of voodoo magic to properly achieve
>> move semantic.
>
> Is a reference implementation available? Is it too early to start using it?
>
In order to use unique_ptr you need first to have a compiler which
properly supports rvalue references. These can be hard to find nowadays,
as the feature has not yet been standardized, although the situation is
quickly improving. For example GCC has very recently added the feature
in v4.3 (http://gcc.gnu.org/gcc-4.3/cxx0x_status.html). If you are lucky
enough to have one of those compilers, most probably they already ship a
version of unique_ptr (it's a sort of benchmark for the feature, you
know). In any case, you can find reference implementations on the
internet by just googling unique_ptr.
So it looks like their are moves to deprecate auto_ptr in favor of unique_ptr (which has the same semantics). But it needs a compiler that supports the proposed new features in the upcoming version of C++.
But there is still another meeting and thus vote to come so things could change before the standard is made concrete.