Why does the C++17 standard not allow converting a string to a bool?

153 views Asked by At

As per cppref, std::from_chars can convert a string to an integer. In C++, bool is an integral type. So I think the following code is intuitive and expressive:

auto const sv = "true"sv;
auto b = bool{};
std::from_chars(sv.data(), sv.data() + sv.size(), b); // compiler error
assert(b);

However, libc++ explicitly deleted the overloaded function:

from_chars_result from_chars(const char*, const char*, bool, int = 10) = delete;

I just wonder:

Why does the C++17 standard not allow converting a string to a bool?

2

There are 2 answers

0
user12002570 On BEST ANSWER

This is LWG 3266 which points out that:

[charconv.to.chars] does not present an overload for bool (because it is neither a signed nor unsigned integer type), so an attempt to call to_chars with a bool argument would promote it to int and unambiguously call the int overload of to_chars.

This was not intended, since it is not obvious that the correct textual representation of a bool is 0/1 (as opposed to, say, "true"/"false").

The user should cast explicitly if he wants the 0/1 behavior. (Correspondingly, there is no bool overload for from_chars in the status quo, and conversions do not apply there because of the reference parameter.)

3
Miles Budnek On

bool is not an integer-type as used by <charconv> (even though it is an integer type, without the hyphen).

From [charconv.syn]:

When a function is specified with a type placeholder of integer-type, the implementation provides overloads for all cv-unqualified signed and unsigned integer types and char in lieu of integer-type.

And from [basic.fundamental]:

There are five standard signed integer types: “signed char”, “short int”, “int”, “long int”, and “long long int”. In this list, each type provides at least as much storage as those preceding it in the list. There may also be implementation-defined extended signed integer types. The standard and extended signed integer types are collectively called signed integer types.

For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: “unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”, and “unsigned long long int”. Likewise, for each of the extended signed integer types, there exists a corresponding extended unsigned integer type. The standard and extended unsigned integer types are collectively called unsigned integer types.

So std::from_chars is defined for signed char, short int, int, long int, long long int, unsigned char, unsigned short int, unsigned int, unsigned long int, unsigned long long int, and char (as well as any implementation-defined extended signed and unsigned integer types). Since bool is not among those types, std::from_chars isn't defined for it.


It's important to note that even if bool was among the integer types, it wouldn't do what you want. std::from_chars only accepts digits (possibly with a leading - sign). "true" would not parse successfully.