m***@gmail.com
2018-10-24 10:09:26 UTC
Hello, consider the following point of view
std::string is to char*, what is std::unique_ptr<T> to T* (minus copying)
To write an interface that accepts strings (pre C++17) it is acceptable to
write
void f(const char*);
void f(const std::string&);
To write an interface that accepts T it is acceptable to write
void f(const T*);
void f(const T&);
It is NOT acceptable to write void f(const std::unique_ptr<T>&); as the
interface becomes dependent on how the object is stored.
There are two problems here,
- first we give advice that contradicts the string example (the interface
is depend on how the string is stored)
- second writing a void f(const std::unique_ptr<T>&); *actually buys
something*, it buys us transparent interface - that is why people do it!.
Enter C++17
The string situation is *further *improved
void f(std::string_view);
We can do what we preach and have an interface that does not depend on how
the string is stored while at the same time keep the interface transparent
on the call site.
The situation with objects is unchanged.
But does it have to be that way? Why not have
void f(observer_ptr<const X>);
*instead of *
void f(const T*);
*AND*
let std::unique_ptr<X> *implicitly *convert to observer_ptr<X>
This will closely match the behavior of std::string -
Both will now have A) raw storage form B) managed storage form C) observing
form.
In both raw storage is explicit call, however observing is implicit
conversion.
Because observer_ptr does not convert to raw pointer, it will be safe to
use even with old APIs that might do manual lifetime management
void friendly(observer_ptr<C> c) { if(c) std::cout<<*c<<'\n'; }
void evil(C* c){ delete c; }
auto c = std::make_unique<C>();
friendly(c); //< happy, transparent usage
evil(c); //< nope
auto p = observer_ptr(c);
evil(p); //< nope
We will hit multiple birds
- Have consistency with other std objects that do or will use a view form
- Give perfect alternative for writing interfaces that take managing smart
pointers only to use the managed object
- Find observer_ptr a meaning for existence, way and beyond "documenting
usage".
Thoughts? Any downsides I missed?
std::string is to char*, what is std::unique_ptr<T> to T* (minus copying)
To write an interface that accepts strings (pre C++17) it is acceptable to
write
void f(const char*);
void f(const std::string&);
To write an interface that accepts T it is acceptable to write
void f(const T*);
void f(const T&);
It is NOT acceptable to write void f(const std::unique_ptr<T>&); as the
interface becomes dependent on how the object is stored.
There are two problems here,
- first we give advice that contradicts the string example (the interface
is depend on how the string is stored)
- second writing a void f(const std::unique_ptr<T>&); *actually buys
something*, it buys us transparent interface - that is why people do it!.
Enter C++17
The string situation is *further *improved
void f(std::string_view);
We can do what we preach and have an interface that does not depend on how
the string is stored while at the same time keep the interface transparent
on the call site.
The situation with objects is unchanged.
But does it have to be that way? Why not have
void f(observer_ptr<const X>);
*instead of *
void f(const T*);
*AND*
let std::unique_ptr<X> *implicitly *convert to observer_ptr<X>
This will closely match the behavior of std::string -
Both will now have A) raw storage form B) managed storage form C) observing
form.
In both raw storage is explicit call, however observing is implicit
conversion.
Because observer_ptr does not convert to raw pointer, it will be safe to
use even with old APIs that might do manual lifetime management
void friendly(observer_ptr<C> c) { if(c) std::cout<<*c<<'\n'; }
void evil(C* c){ delete c; }
auto c = std::make_unique<C>();
friendly(c); //< happy, transparent usage
evil(c); //< nope
auto p = observer_ptr(c);
evil(p); //< nope
We will hit multiple birds
- Have consistency with other std objects that do or will use a view form
- Give perfect alternative for writing interfaces that take managing smart
pointers only to use the managed object
- Find observer_ptr a meaning for existence, way and beyond "documenting
usage".
Thoughts? Any downsides I missed?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a04b52-e5cd-4543-86c5-5a0068f9647b%40isocpp.org.
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/81a04b52-e5cd-4543-86c5-5a0068f9647b%40isocpp.org.