New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better semantics for try_get #215
Comments
A pointer can either be |
While they both can be used to achieve the same effect, I believe an There are also more practical reasons: I have opened this ticket because I was confused about "who owns the memory pointed at by this pointer?" "Who's responsible for deallocating it?", when reviewing a certain PR that used entt. In case of a pointer, one must know the implementation details of the library, they must remember that in this particular case registry owns the memory and memory management shouldn't be a concern. In other words, |
|
The reference returned by |
I’m all for modern C++ but I’m yet to find a place where |
A pointer has meaning in C++. It is self documenting. A pointer is nullable. A pointer has a different meaning to a reference and this is well understood by C++ programmers. |
I haven't been complaining, I've been trying to improve (your?) library. Unlike a pointer, a reference communicates an implicit contract that the caller is "borrowing" the value and shouldn't be concerned about its lifetime. It's your call, I believe I have provided all the arguments. If you're been looking for it, this is the perfect idiomatic fit for |
A pointer has meaning in C++. It is self documenting. A pointer is nullable. A pointer has a different meaning to a reference and this is well understood by C++ programmers. In “good code” a raw pointer never owns memory so you don’t have to deallocate it. A pointer is a nullable reference. |
Let's take a deeper look into the issue before to continue discussing. I think there is a basic misunderstanding in the OP's request (emphasis mine):
To be clear, if(registry.has<C>(entity)) {
C *instance = ®istry.get<C>(entity);
} Using an if(registry.has<C>(entity)) {
C instance = registry.get<C>(entity);
} The subtle difference is that you're obtaining a copy of the component, that is useless most of the times, other than a waste of CPU cycles. That said, I think we agree on the fact that we cannot use std::optional<std::reference_wrapper<C>> Put aside the fact that it requires to include two extra headers in struct C { int value; };
// ...
if(auto opt = registry.try_get<C>(entity); opt) {
opt->get().value = 42;
} That is, the combination of an if(auto *c = registry.try_get<C>(entity); c) {
c->value = 42;
} To be honest, it seems less intuitive to me, at least for a C++ programmers, but this is a sort of personal opinion. Just to be sure, is this what you're asking for? Are you proposing to replace the return type of |
As a side question:
For what are you using |
@sssilver Any feedback on the questions above? |
@skypjack Using EnTT for a cross-platform video game. We'll be happy to credit you when the game is launched, and will definitely let you know to update your Action page. With regards to |
You're welcome, thank you for pointing it out. Discussions on the library are always welcome. 👍 |
I accidently stumbled upon this old ticket and I understand where the author is coming from. Whenever we get a There was actually a discussion on optional references on this: However, for entt - an alternative solution would be to fill into what the standard is missing, and implement |
Uhm... isn't it a bit overkilling? It introduces yet another specialization to clarify the semantic of a function return type that is imho clear enough already. I can understand that a free function |
Even more: if I understand Core Guidlines, you should never use owning raw pointers in modern C++ API anyway. And if you need to you should use |
Maybe what's needed is an additional note in the method's documentation? /**
* \note The registry retains ownership of the returned pointer(s).
*/ |
This is probably our best bet. Do you want to open a PR for that @codylico ? 🙂 |
Yes, I can do that. PR from which branch? |
@codylico sorry, sleeping time for me 8 hours ago. 🙂 I'd say branch |
Hi,
Presently
registry::try_get()
returns a pointer to an entity that isnullptr
if the requested entity doesn't exist.Since C++17 finally has optionals, its semantics would be improved if instead it returned a reference to an entity, wrapped in an
std::optional
. This would make the interface more predictable and communicate design intent more explicitly.Happy to open a PR for this if that'd help.
The text was updated successfully, but these errors were encountered: