问题
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