operator bool()
conversion function for the vector<bool>
and bitset
proxy classes as implicit.
While this paper has no suggested applications of the feature beyond boolean conversions, the committee might want to explore explicit
pointer conversion operators for the library smart pointers.
The paper would also resolve LWG issue 644 as NAD.
(A couple of Minor editorial nits (typos etc) are also fixed without comment.)
nullptr_t
is available. The issue is that the unspecified bool idiom supports a slightly wider range of comparisons that make sense for pointers
basic_ios
for concern this might break existing code written against an implementation supporting defect report 468. Suggestion is to follow with wording that allows both implementations in this case, under some as-if clause.
Change 19.4.2.1 [sys.errcode.overview]
namespace std { class error_code { public: ... // observers: value_type value() const; const error_category& category() const; posix_errno posix() const; string message() const; wstring wmessage() const; explicit operatorunspecified-bool-type() const; ... }; } // namespace std ... explicit operatorunspecified-bool-type() const;
-11- Returns: If value() != value_type(), returns a value that will evaluate true
in a boolean context; otherwise,
returs a value that will evaluate false
. The return type shall not be convertible to int.
-12- Throws: Nothing.
-13- [ Note: This conversion can be used in contexts where a bool is expected (e.g., an if condition); however, implicit
conversions (e.g., to int) that can occur with bool are not allowed, eliminating some sources of user error. One
possible implementation choice for this type is pointer to member. - end note ]
Change 20.5.14.2 [func.wrap.func]:
namespace std { template<class> class function; // undefined template<class R, class... ArgTypes> class function<R(ArgTypes...)> : public unary_function<T1, R> // iff sizeof...(ArgTypes) == 1 and ArgTypes contains T1 : public binary_function<T1, T2, R> // iff sizeof...(ArgTypes) == 2 and ArgTypes contains T1 and T2 { public: ... // 20.5.14.2.3, function capacity: explicit operatorunspecified-bool-type() const; ...private: // 20.5.14.2.6, undefined operators: template<class R2, class... ArgTypes2> bool operator==(const function<R2(ArgTypes2...)>&); template<class R2, class... ArgTypes2> bool operator!=(const function<R2(ArgTypes2...)>&);}; } // namespace std
and 20.5.14.2.3 [func.wrap.func.cap]:
explicit operatorunspecified-bool-type() const
-1- Returns: if *this has a target, returns a value that will evaluate true
in a boolean context; otherwise, returns a value that will evaluate false
in a boolean context. The value type returned shall not be convertible to int.
-2- Throws: nothing.
-3- [ Note: This conversion can be used in contexts where a bool is expected (e.g., an if condition); however, implicit conversions (e.g., to int) that can occur with bool are not allowed, eliminating some sources of user error. One possible implementation choice for this type is pointer-to-member. - end note ]
and remove 20.5.14.2.6 [func.wrap.func.undef]:
template<class R2, class... ArgTypes2> bool operator==(const function<R2(ArgTypes2...)>&); template<class R2, class... ArgTypes2> bool operator!=(const function<R2(ArgTypes2...)>&);
-1- These member functions shall be left undefined.
-2- [ Note: the boolean-like conversion opens a loophole whereby two function instances can be compared via or !=. These undefined void operators close the loophole and ensure a compile-time error. - end note ]
Change 27.6.1.1.3 [istream::sentry]
namespace std { template <class charT,class traits = char_traits<charT> > class basic_istream<charT,traits>::sentry { typedef traits traits_type; // bool ok_; exposition only public: explicit sentry(basic_istream<charT,traits>& is , bool noskipws = false); ~sentry(); explicit operator bool() const { return ok_; } private: sentry(const sentry&); // not defined sentry& operator=(const sentry&); // not defined }; }
Change 27.6.2.4 [ostream::sentry]
namespace std { template <class charT,class traits = char_traits<charT> > class basic_ostream<charT,traits>::sentry { // bool ok_; exposition only public: explicit sentry(basic_ostream<charT,traits>& os); ~sentry(); explicit operator bool() const { return ok_; } private: sentry(const sentry&); // not defined sentry& operator=(const sentry&); // not defined }; }