Closed Minavery closed 1 week ago
The error is expected, formatting of non-void pointers is intentionally disallowed although there were some gaps in diagnostic in earlier versions. You should either format the value or convert to void*
/ use fmt::ptr
.
The error is expected, formatting of non-void pointers is intentionally disallowed although there were some gaps in diagnostic in earlier versions. You should either format the value or convert to
void*
/ usefmt::ptr
.
Okay.
I find my code pasted has some error. it should be:
template<>
struct fmt::formatter<float *> : formatter<string_view> {
auto format(float* pointer, fmt::format_context& ctx) const {
if (pointer != nullptr) {
auto&& str = fmt::format("*{}={}", (void*)pointer, *pointer);
return formatter<fmt::string_view>::format(str, ctx); }
else {
return formatter<fmt::string_view>::format("nullptr", ctx);
}
}
};
int main() {
float a = 0.0;
fmt::print("{}\n",&a);
}
but there is compile error "Formatting of non-void pointer is disallowed. " yet. How could I fomat a pointer same as fmt 8.0?
You can do it by wrapping a pointer in your type and providing a formatter for it:
#include <fmt/format.h>
template <typename T>
struct ptr_view {
T* value;
};
template <typename T>
auto ptr(T* p) -> ptr_view<T> { return {p}; }
template <typename T>
struct fmt::formatter<ptr_view<T>> : formatter<string_view> {
auto format(::ptr_view<T> pointer, fmt::format_context& ctx) const {
if (pointer.value != nullptr) {
auto&& str = fmt::format("*{}={}", (void*)pointer.value, *pointer.value);
return formatter<fmt::string_view>::format(str, ctx); }
else {
return formatter<fmt::string_view>::format("nullptr", ctx);
}
}
};
int main() {
float a = 0.0;
fmt::print("{}\n", ptr(&a));
}
You can do it by wrapping a pointer in your type and providing a formatter for it:
#include <fmt/format.h> template <typename T> struct ptr_view { T* value; }; template <typename T> auto ptr(T* p) -> ptr_view<T> { return {p}; } template <typename T> struct fmt::formatter<ptr_view<T>> : formatter<string_view> { auto format(::ptr_view<T> pointer, fmt::format_context& ctx) const { if (pointer.value != nullptr) { auto&& str = fmt::format("*{}={}", (void*)pointer.value, *pointer.value); return formatter<fmt::string_view>::format(str, ctx); } else { return formatter<fmt::string_view>::format("nullptr", ctx); } } }; int main() { float a = 0.0; fmt::print("{}\n", ptr(&a)); }
Thanks. It works fine. I want to know why there is difference between pointer and others?
The motivation is explained in https://accu.org/journals/overload/17/89/wilson_1539/, Defective argument types.
I find my old code is invalid when using fmt 10.2.1.
''' template<> struct fmt::formatter<float > : formatter {
auto format(float pointer, fmt::format_context& ctx) const {
if (pointer != nullptr) {
auto&& str = fmt::format("{}={}", (void)pointer, *pointer);
return formatter::format(str, ctx); }
else {
return formatter::format("nullptr", ctx);
}
} };
int main() { float a = 0.0; fmt::print("{}\n",&a); } '''
error is "Formatting of non-void pointer is disallowed."
Compiler Explorer Code.cpp.zip