I have the following case:
T* get_somthing(){
std::vector vec; //T is trivally-copyable
//fill vec
T* temp = new T[vec.size()];
memc
P.S. Changing the design is not an option. Using the std::vector there is mandatory. Returning a pointer to array is also mandatory.
Changing the design is your best option. I recommend reconsidering this stance.
There is (currently†) no way to "steal" the buffer of a vector, so given the (silly††) limitations stated in the question, copying is the way to go.
† Tomasz Lewowski linked a proposal that would change this if it is included in a future standard: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4359.pdf (Edit: as pointed out, it was rejected from c++17)
†† Silly until justified by concrete requirements.
It is a wrapper between two modules. One need vector the other need pointer.
Presumably, the other interface that needs the pointer, delegates the destruction of the buffer to the caller, possibly using some sort of call back like void delete_somthing(T*)
. Taking ownership without giving it back would have been very bad design, in my opinion.
In case you do have control of the destruction, you can store the vector in a map, and erase the vector, when the pointer is passed for destruction:
std::unordered_map<T*, std::vector<T>> storage;
T* get_somthing(){
std::vector<T> vec; //T is trivally-copyable
//fill vec
T* ptr = vec.data();
storage[ptr] = std::move(vec);
return ptr;
}
void delete_somthing(T* ptr){
storage.erase(ptr);
}
Edit: This idea doesn't work because there is no way to prevent the implicit call to the destructors of base classes (thanks, molbdnilo). That they are called is, if I think of it, a good thing.
~vector()
is not virtual (is there a requirement in the standard for being or not being virtual?) this should work as long as you explicitly use your type.
By inheriting you would retain all the benefits, in particular the memory management -- except for the final bit (which you don't want).
The first thing you should do is to get up, go to the one responsible for this design and (verbally in a professional manner) punch him/her in the face: It's a mess.
Then, there's a way in C++11 to have a std::vector
with automatic storage duration and have it not call its destructor:
std::vector
into an union
Like so:
template<typename T>
union Ugly {
std::vector<T> vec;
Ugly() {
new (&vec) std::vector<T>(); // Construct
}
~Ugly() {
// Don't destruct
}
};
T* get_something(){
Ugly mess;
//fill mess.vec
return mess.vec.data();
}
I'm not 100% sure whether this still counts as valid C++11, but it should "work". Now excuse me, I need to wash my hands to get rid of the crying feeling of shame for this code ...
Oh, and one more thing: How do you intend to release the memory that the std::vector
had allocated? You know, you can't (reliably) use the pointer returned by the member function data()
for that!