Opened 8 years ago

Last modified 8 years ago

#10393 new Feature Requests

Add begin/end specialization for optional<T> type

Reported by: khimru@… 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();

}

}

Change History (1)

comment:1 by rob.desbois@…, 8 years ago

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):

  if (opt_container)
    for (auto&& element : *opt_container)
    {}

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 the optional<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.

Note: See TracTickets for help on using tickets.