Opened 8 years ago
Last modified 8 years ago
#10393 new Feature Requests
Add begin/end specialization for optional<T> type
Reported by: | Owned by: | Fernando Cacciola | |
---|---|---|---|
Milestone: | Boost 1.57.0 | Component: | optional |
Version: | Boost 1.56.0 | Severity: | Cosmetic |
Keywords: | optional, for, begin, end | Cc: |
Description
optional<T> could be used in many places as if it was just T, but, since C++ does not apply two levels of constructions one could not use this natural looking construct for optional containers:
if (opt_container) {
for (auto& element : opt_container) {
...
}
}
Simple specialization of begin()/end() functions could solve this problem:
namespace std {
template<class T> inline auto begin(const boost::optional<T>& opt) -> decltype(opt.get().begin()) {
return opt.get().begin();
}
template<class T> inline auto begin(boost::optional<T>& opt) -> decltype(opt.get().begin()) {
return opt.get().begin();
}
template<class T> inline auto end(const boost::optional<T>& opt) -> decltype(opt.get().end()) {
return opt.get().end();
}
template<class T> inline auto end(boost::optional<T>& opt) -> decltype(opt.get().end()) {
return opt.get().end();
}
}
You'd still have to check that the optional is initialized before doing so though. A simpler fix is to use the optional's dereference operator (when the optional<T> is initialized):
A really useful facility would be
begin()
&end()
overloads/specializations that could return an empty sequence when the optional is uninitialized, enabling direct passing of theoptional<T>
object to the range-for *without checking that it's initialized*. Given that in many cases (including standard library components) there's no way to construct a non-singular iterator without an underlying container this might be tricky...though a transparent wrapping iterator might do the trick.