-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Please consider adding a default formatter for scoped enumerations #2704
Comments
Scoped enums are not formattable as |
However, we could provide a generic formatter under a different name e.g. |
@vitaut The If you are following the list of enabled |
@vitaut Sorry, didn't see the other comment. Will wait for your thoughts on unscoped enumerations before responding. |
Unscoped enumerations are implicitly convertible to the underlying type so they are formatted as the underlying type. This is consistent with usual C++ rules, e.g. (https://godbolt.org/z/5qb11f86G) enum E {};
enum class EC {};
void print(int) {}
int main() {
print(E()); // OK
print(EC()); // error
} |
@vitaut I was thinking that because enumerations aren't explicitly covered in the list of enabled Based on this point, I don't think it's wise to supply a specialization I mentioned in the library, given that when people switch to C++20, it won't be there. I will fix the |
{fmt} now support a simplified API ( #include <fmt/format.h>
namespace kevin_namespacey {
enum class film { house_of_cards, american_beauty, se7en = 7};
auto format_as(film f) { return fmt::underlying(f); }
}
int main() {
fmt::print("{}", kevin_namespacey::film::se7en);
} |
@vitaut Thanks for taking the time to work on a solution. A couple of thoughts come to mind. Not meant as a criticism - just something to consider. Seems that a function with a predefined name #include <fmt/format.h>
namespace util::fmt {
template<typename T, typename std::enable_if_t<std::is_enum_v<T>, int> = 0>
typename std::underlying_type_t<T> format_as(T e)
{
return static_cast<typename std::underlying_type_t<T>>(e);
}
}
using util::fmt::format_as;
namespace unit1 {
enum class count_t { one, two, three};
using util::fmt::format_as;
}
namespace unit2 {
enum class count_t {one, three, two};
using util::fmt::format_as;
}
enum class count_t { three, two, one};
int main()
{
auto print_three = []() -> void
{
enum class count_t {zero, one, two, three};
fmt::print("{}\n", count_t::three);
};
print_three();
fmt::print("{}\n", unit1::count_t::three);
fmt::print("{}\n", unit2::count_t::three);
fmt::print("{}\n", count_t::three);
return 0;
}
Another thought is that this solution cannot be easily detached from {fmt} to use it on its own and when people switch to C++20, all code relying on |
Thanks for the suggestion. Having a reusable |
Agreed. This is also what's most likely will happen in most projects. Having said that, I'm not sure what a good solution would be - I simply don't know the project well enough to offer a good suggestion. Maybe |
I have the same problem when using fmt 8.1.1, whilc 8.0.1 is ok. And I don't think this modification in fmt 8.1.1 is convenient |
As suggested by @gh-andre I added a generic #include <fmt/format.h>
namespace kevin_namespacey {
enum class film { house_of_cards, american_beauty, se7en = 7};
using fmt::enums::format_as;
}
int main() {
fmt::print("{}", kevin_namespacey::film::se7en);
} I think it's a reasonable compromise between usability and avoiding undesirable conversions. |
I'm switching from
fmt
v6 and all of a sudden allformat
calls taking scopedenum
values fail and it would take many specialized formatters to handle them in the same way.Please consider adding a generic
enum
formatter along these lines, so it just works out of the box:Thanks!
The text was updated successfully, but these errors were encountered: