Disabling implicit conversion of enum class -> int
Closed this issue ยท 15 comments
It seems this feature was added based on #391 and #984, but I personally consider this a bug: the entire purpose of enum class
is to prevent any kind of implicit casting. If I wanted to format it as an integer, I should be forced to cast it to an integer or create my own formatter
. Is there any recommended way to disable this? Perhaps a preprocessor option?
I have a custom formatter
for some specific enum class
es, but this implicit casting prevents me from being able to safely forward declare any of my enum class
es, since if the custom formatter
doesn't get included, format
falls back to the default enum class
-> int
conversion. My formatter
uses unique formatting specifiers that don't match anything found with the default int
formatter, so when the wrong formatter is used a format_error
is thrown.
You can also forward declare the formatter specialization, then trying to format then is a compile error.
There is no way to disable formatting of enums other than what Jonathan suggested.
Unfortunately that suggestion doesn't fix the problem, since it's still "dangerous by default". Is there any chance that an option might be added like I suggested?
Would you happen to know if this implicit casting behavior is part of std::format? I looked through the proposals I could find, but couldn't find any mention of enum class formatting behavior.
Is there any chance that an option might be added like I suggested?
I don't think it's worth adding yet another configuration option. You could use compile-time format string checks to diagnose this earlier or make your format specs compatible with standard ones if possible.
Would you happen to know if this implicit casting behavior is part of std::format?
I don't recall from the top of my head - please check the current specs at https://eel.is/c++draft/format.
It seems like that fmt now ignores ostream overloads for enum classes. @vitaut, is this intended behavior? Are there any recommended workarounds?
Edit: Never-mind and apologies for the noise. The overload still works and seems to take precedence over the to int conversion.
I recommend providing a formatter
specialization.
To me, the implicit conversion is just a bug. It goes against the enum class policy. In C++23, std::to_underlying will be introduced for this purpose. If someone wants to display an enum class as an integer it should convert it explicitly or provide a formatter specialization. Without them, this should result in a compiler error.
https://eel.is/c++draft/format is silent about enum class'es. And the examples I found on the web show that an enum class is considered as a user-defined type and requires a formatter.
Fwiw, my eventual solution was to replace all calls to fmt functions with my own format/print function that checks for enum classes at compile time. Obviously this is not really reasonable for any kind of established project.
@PazerOP, could you provide an example illustrating the specific problem you had with enum classes? (preferably a godbolt link)
Anyway, thinking more of it, the fact that there is no implicit conversion from scoped enums to integers does suggest that they shouldn't be formatted as integers by default, so reopening.
I don't have a specific release date yet.