I have a class:
class MyClass{
public:
std::string _cachedString;
std::string_view get_string(){
_cachedString = "abc";
return _cachedString;
}
};
template<>
class fmt::formatter<MyClass>{
public:
template<typename ParseContext>
constexpr auto parse(ParseContext& ctx){return ctx.begin();}
template <typename FormatContext>
constexpr auto format( MyClass& t, FormatContext& ctx){
return format_to(ctx.out(), "({})", t.get_string());
}
};
I looked this up, and found that you need to pass const MyClass& t
as argument to format function. But in my case, since I am modifying the object, I cannot. When I compile this code, I get this error:
undefined reference to `fmt::v8::detail::value<fmt::v8::basic_format_context<fmt::v8::appender, char> >::value(fmt::v8::detail::unformattable_const)'
which goes away when I remove the line calling fmt::format on MyClass object. How to rectify this?
You should make the format
function itself const:
template<>
struct fmt::formatter<MyClass> {
constexpr auto parse(format_parse_context& ctx) {
return ctx.begin();
}
template <typename FormatContext>
constexpr auto format(MyClass& t, FormatContext& ctx) const {
return format_to(ctx.out(), "({})", t.get_string());
}
};
Otherwise your example works in recent versions of {fmt} (godbolt):
int main() {
MyClass c;
fmt::print("{}", c);
}
However, as @super correctly pointed out in the comments, a better solution is to make _cachedString
mutable and get_string
const:
class MyClass {
public:
mutable std::string _cachedString;
std::string_view get_string() const {
_cachedString = "abc";
return _cachedString;
}
};