Finally. I believe that these are compile time errors in C++17.
No, they are not.
struct tribool { int value;
EXPLICIT operator bool() const { return value != 0; } };
int main() { tribool b1, b2; b1 < b2; b1 + b2; b1 + 5; b1 * 2; }
$ g++ -std=c++17 -DEXPLICIT= -o tribool_conv tribool_conv.cpp
$ g++ -std=c++17 -DEXPLICIT=explicit -o tribool_conv tribool_conv.cpp tribool_conv.cpp: In function ‘int main()’: tribool_conv.cpp:11:8: error: no match for ‘operator<’ (operand types are ‘tribool’ and ‘tribool’) b1 < b2; ~~~^~~~ tribool_conv.cpp:11:8: note: candidate: operator<(int, int) <built-in> tribool_conv.cpp:11:8: note: no known conversion for argument 2 from ‘tribool’ to ‘int’ tribool_conv.cpp:12:8: error: no match for ‘operator+’ (operand types are ‘tribool’ and ‘tribool’) b1 + b2; ~~~^~~~ tribool_conv.cpp:12:8: note: candidate: operator+(int, int) <built-in> tribool_conv.cpp:12:8: note: no known conversion for argument 2 from ‘tribool’ to ‘int’ tribool_conv.cpp:13:8: error: no match for ‘operator+’ (operand types are ‘tribool’ and ‘int’) b1 + 5; ~~~^~~ tribool_conv.cpp:13:8: note: candidate: operator+(int, int) <built-in> tribool_conv.cpp:13:8: note: no known conversion for argument 1 from ‘tribool’ to ‘int’ tribool_conv.cpp:14:8: error: no match for ‘operator*’ (operand types are ‘tribool’ and ‘int’) b1 * 2; ~~~^~~ tribool_conv.cpp:14:8: note: candidate: operator*(int, int) <built-in> tribool_conv.cpp:14:8: note: no known conversion for argument 1 from ‘tribool’ to ‘int’
Damn, you got me here. Good illustration. So the legal operations of a bool depends on whether it's the result of an explicit or implicit conversion. Such a think would never have occurred to me. I suppose it's obvious what I think about that idea so I won't comment. Another confession: I didn't realize that optional used and explicit conversion. Maybe that changes something. I've never thought that conversion to bool from optional was ever a good idea - be it implicit or explicit. But I guess that's just me. Robert Ramey