C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Delete...why not a parameter by reference?!

From: organicoman <organicoman_at_[hidden]>
Date: Sun, 24 Aug 2025 21:35:17 +0100
> If the designer of the type explicity express that his type is not copiable, why fight with his design, and use references?> All what you've said so far can be answered with good argument, but let's not deviate from the main ideaFirst, because reference are not even objects and cannot be stored in arrays, containers and can't be dynamically allocated or deallocated and they can't be destroyed -- have you ever tried std::vector<int&>, std::array<int&>, int& arr[1] or new (int&)[1] ? None of the work because references are not objects, they don't have a size or a layout and for all that matters they may not even occupy observable space (whatever the implementation uses to implement a reference is not visible to the program).Very correct, that's why I didn't deviate into that with Simon.Also he mentioned indirection and inefficiency of passing by reference,....well if a compiler can optimize a non used variable, definitely it can collapse a reference into a pointer.Secondly, vectors's member function are only instantiated if necessary and most do not even require the value type to be CopyInsertable: a vector<unique_ptr<int>> object is totally fine because the only requirement on instantiation is that:"The requirements that are imposed on the elements depend on the actual operations performed on the container. Generally, it is required that element type meets the requirements of Erasable, but many member functions impose stricter requirements. This container (but not its members) can be instantiated with an incomplete element type if the allocator satisfies the allocator completeness requirements." see <https://cppreference.com/w/cpp/container/vector.html>Then elements of type unique_ptr<int> can be inserted in such a vector using "void push_back(unique<int>&& value)" because the requirements of being MoveInsertable is being met by unique_ptr<int>, see <https://cppreference.com/w/cpp/container/vector/push_back.html>Last but not least, if you manage to store a non owning reference type in a vector by using "int*" (or "std::ref<int>", which is really a thin wrapper around "int*"), then your vector loses deep ownership of the referred to elements. A vector<int*> has uses cases on its own as a collection of non owning references, but it absolutely need to only ever refer to int objects from a (guaranteed) larger lexical scope, for instance the elements of another already initialized list<int> data member of some class and the vector<int*> would be a sibling data member. A vector<int*> can never assume ownership of the int objects it refers to: the int objects absolutely need to be owned in a larger scoped object. In contrast, a vector<unique_ptr<int>> has a ***wildly*** different behavior and intent, as it assumes deep ownership of the int objects.I think the above answers a lot of Simon’s concerns. On August 24, 2025 7:12:04 a.m. EDT, organicoman via Std-Proposals <std-proposals_at_[hidden]> wrote:
auto val = v[1];creates a copy and does not store a reference even though a reference was returned. You have to writeauto &val = v[1];That's what I referred to as unintentional error.One character missing and the meaning changes, now compare it to your example snippet. And it is certainly a good idea that operator[] returns a reference because you can also store really large objects inside containers. You might even want to be able to writev[1] = 2;Same function with two actions, that breaks the single responsibility principle. which is only possible with a reference.A reference also means you can put non-copyable objects inside the container, That's certainly a bad decision, and I advice against that.like unique_ptr. You see, a reference is almost mandatory here for C++ to succeedIf the designer of the type explicity express that his type is not copiable, why fight with his design, and use references?All what you've said so far can be answered with good argument, but let's not deviate from the main idea.One more additional thing: If you assign a new address to a pointer after it has been deleted and you never read from that pointer again, the compiler is allowed to optimize away this assignment. It does not matter that others have a reference to it. There is currently no legal way to write the kind of code in C++ and actually do what you want. (And disallowing this optimization will not get you any friends.) This is why this belongs into the compiler as a flag because you cannot express it in the language.This paragraph is the most interesting. I need to investigate this.

Received on 2025-08-24 20:35:26