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 operator unspecified-bool-type() const;
...
};
} // namespace std
...
explicit operator unspecified-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 operator unspecified-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
};
}