forked from OSchip/llvm-project
Fix PR19460 - std::ios is convertible to int.
std::basic_ios has an operator bool(). In C++11 and later it is explicit, and only allows contextual implicit conversions. However explicit isn't available in C++03 which causes std::istream (et al) to have an implicit conversion to int. This can easily cause ambiguities when calling operator<< and operator>>. This patch uses a "bool-like" type in C++03 to work around this. The "bool-like" type is an arbitrary pointer to member function type. It will not convert to either int or void*, but will convert to bool. llvm-svn: 290750
This commit is contained in:
parent
a8d45de6ce
commit
2131a71c05
|
@ -585,9 +585,22 @@ public:
|
|||
typedef typename traits_type::pos_type pos_type;
|
||||
typedef typename traits_type::off_type off_type;
|
||||
|
||||
#if defined(_LIBCPP_CXX03_LANG)
|
||||
private:
|
||||
struct __bool_tag {};
|
||||
typedef void (basic_ios::*_BoolType)(__bool_tag) const;
|
||||
void __true_value(__bool_tag) const {}
|
||||
|
||||
public:
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_EXPLICIT
|
||||
operator bool() const {return !fail();}
|
||||
operator _BoolType() const {
|
||||
return !fail() ? &basic_ios::__true_value : nullptr;
|
||||
}
|
||||
#else
|
||||
_LIBCPP_ALWAYS_INLINE
|
||||
_LIBCPP_EXPLICIT operator bool() const {return !fail();}
|
||||
#endif
|
||||
|
||||
_LIBCPP_ALWAYS_INLINE bool operator!() const {return fail();}
|
||||
_LIBCPP_ALWAYS_INLINE iostate rdstate() const {return ios_base::rdstate();}
|
||||
_LIBCPP_ALWAYS_INLINE void clear(iostate __state = goodbit) {ios_base::clear(__state);}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
// operator unspecified-bool-type() const;
|
||||
|
||||
#include <ios>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
int main()
|
||||
|
@ -22,4 +23,10 @@ int main()
|
|||
assert(static_cast<bool>(ios) == !ios.fail());
|
||||
ios.setstate(std::ios::failbit);
|
||||
assert(static_cast<bool>(ios) == !ios.fail());
|
||||
static_assert((!std::is_convertible<std::ios, void*>::value), "");
|
||||
static_assert((!std::is_convertible<std::ios, int>::value), "");
|
||||
static_assert((!std::is_convertible<std::ios const&, int>::value), "");
|
||||
#if TEST_STD_VER >= 11
|
||||
static_assert((!std::is_convertible<std::ios, bool>::value), "");
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue