With std::optional standardizing, can we stop using nullptr in new code and deprecate it? [closed]

两盒软妹~` 提交于 2020-01-07 05:46:06

问题


From time immemorial, when passing pointers to or from functions, we tend to special-case the null pointer:

 p = get_pointer_to_the_foo(args);
 if (p == nullptr) { /* foo is inaccessible, do one thing */ }
 else { /* we can access foo, do something else */ }

and this is an inheritance from C. Now, we occasionally would do the same with other types, e.g. using a signed type to represent either a valid non-negative value, and, say, -1 or to indicate an error.

The latter pattern will now be finally deprecated with the onset of std::optional: std::optional<unsigned> is either nullopt or a non-negative value. But - what about pointers? After all, nullptr is just one of innumerable invalid pointer values. So, when writing new code (when all of it is C++17) - should we essentially forget about it, and pass around either std::optional<foo_t*>'s or assumed-non-null foo_t *'s?


回答1:


Pointer embed the optional semantic already. Therefore std::optional<T*> would be redundant to say the least and the introduction of said feature won't impact much raw pointers.

This is also true with std::unique_ptr, std::shared_ptr and std::weak_ptr all of which can also be nullptr.

Just like with any new feature we have to ponder what's pragmatic versus our innate urge to use it everywhere it's feasible.




回答2:


As I think my conversation in comments is not sufficient I provide answer to einpoklum comment. This answer is more like suplement to Nir Friedman answer.

Please read http://en.cppreference.com/w/cpp/language/pointer. Pointer is a type. It's have state describe as Null pointer. Pointer is not a CPU's memory address (but it could be implemented like that), it is abstract type that instance point to another object. Most of pointers has relations with corresponding type but not all of them as you can point by void pointer to any object.




回答3:


Because all pointer types can be null, this unfortunately doesn't make sense in C++. You would need people to accept, by convention, that:

unique_ptr<Foo> make_foo();

Never returns a null pointer, even though it can. But then you'd wonder, if the author actually followed the convention, so you'd look at the docs anyway. And if this function never returns nullptr, then the docs should say it anyhow. And if it can, the docs should say it also.

Basically, the idea behind optional is to use the type system to protect people. Particularly to encourage people to write types that are constructed into a valid state immediately. In other words, people often used to write types that were effectively OptionalFoo, because they weren't always in a valid state. So instead, encourage people to write Foo, and use optional<Foo> when they need it. That way, the type Foo is always valid.

However, pointers, raw and smart, just cannot be guaranteed to be in a valid state. Every pointer is already an optional pointer. We can argue over the exact meaning of validity here, but basically you have a precondition on calling * on all pointers. The whole point of optional is to remove preconditions; you don't need to call f.is_valid() because you wrote a Foo instead of an OptionalFoo.

By the way, the reason why pointers cannot make this guarantee in C++ is actually rooted in the absence of destructive move in C++. If you try to write a not_null_unique_ptr, what would the move constructor look like?



来源:https://stackoverflow.com/questions/43044464/with-stdoptional-standardizing-can-we-stop-using-nullptr-in-new-code-and-depr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!