The following example (Compiler Explorer link), taken mostly unaltered from the docs
#include <type_traits> #include <fmt/compile.h> enum class color {red, green, blue}; template <> struct fmt::formatter<color>: formatter<string_view> { // parse is inherited from formatter<string_view>. auto format(color c, format_context& ctx) const -> format_context::iterator; }; auto fmt::formatter<color>::format(color c, format_context& ctx) const -> format_context::iterator { string_view name = "unknown"; switch (c) { case color::red: name = "red"; break; case color::green: name = "green"; break; case color::blue: name = "blue"; break; } return formatter<string_view>::format(name, ctx); } int main() { using fmt::operator""_cf; fmt::print("{}"_cf, color::red); } }
fails with
In file included from <source>:3:
In file included from /opt/compiler-explorer/libs/fmt/trunk/include/fmt/compile.h:15:
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:3601:26: error: non-const lvalue reference to type 'format_context' (aka 'fmt::context') cannot bind to a value of unrelated type 'basic_format_context<back_insert_iterator<basic_memory_buffer<char, 500, allocator<char>>>, char>' (aka 'fmt::generic_context<std::back_insert_iterator<fmt::basic_memory_buffer<char>>, char>')
3601 | return f.format(value, ctx);
| ^~~
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/compile.h:169:14: note: in instantiation of function template specialization 'fmt::detail::write<char, std::back_insert_iterator<fmt::basic_memory_buffer<char>>, color, 0>' requested here
169 | return write<Char>(out, arg);
| ^
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/compile.h:460:13: note: in instantiation of function template specialization 'fmt::detail::field<char, color, 0>::format<std::back_insert_iterator<fmt::basic_memory_buffer<char>>, color>' requested here
460 | return cf.format(out, args...);
| ^
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/compile.h:500:17: note: in instantiation of function template specialization 'fmt::format_to<std::back_insert_iterator<fmt::basic_memory_buffer<char>>, fmt::detail::field<char, color, 0>, color, 0>' requested here
500 | return fmt::format_to(out, compiled, std::forward<Args>(args)...);
| ^
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/compile.h:528:8: note: in instantiation of function template specialization 'fmt::format_to<std::back_insert_iterator<fmt::basic_memory_buffer<char>>, fmt::detail::udl_compiled_string<char, 3, detail::fixed_string<char, 3>{"{}"}>, const color &, 0>' requested here
528 | fmt::format_to(std::back_inserter(buffer), fmt, args...);
| ^
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/compile.h:535:3: note: in instantiation of function template specialization 'fmt::print<fmt::detail::udl_compiled_string<char, 3, detail::fixed_string<char, 3>{"{}"}>, color, 0>' requested here
535 | print(stdout, fmt, args...);
| ^
<source>:27:8: note: in instantiation of function template specialization 'fmt::print<fmt::detail::udl_compiled_string<char, 3, detail::fixed_string<char, 3>{"{}"}>, color, 0>' requested here
27 | fmt::print("{}"_cf, color::red);
| ^
<source>:14:61: note: passing argument to parameter 'ctx' here
14 | auto fmt::formatter<color>::format(color c, format_context& ctx) const
| ^
In file included from <source>:3:
In file included from /opt/compiler-explorer/libs/fmt/trunk/include/fmt/compile.h:15:
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:3601:10: error: no viable conversion from returned value of type 'format_context::iterator' (aka 'basic_appender<char>') to function return type 'std::back_insert_iterator<fmt::basic_memory_buffer<char>>'
3601 | return f.format(value, ctx);
| ^~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/bits/stl_iterator.h:689:11: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'format_context::iterator' (aka 'basic_appender<char>') to 'const back_insert_iterator<basic_memory_buffer<char>> &' for 1st argument
689 | class back_insert_iterator
| ^~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/bits/stl_iterator.h:689:11: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'format_context::iterator' (aka 'basic_appender<char>') to 'back_insert_iterator<basic_memory_buffer<char>> &&' for 1st argument
689 | class back_insert_iterator
| ^~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-14.2.0/lib/gcc/x86_64-linux-gnu/14.2.0/../../../../include/c++/14.2.0/bits/stl_iterator.h:704:7: note: explicit constructor is not a candidate
704 | back_insert_iterator(_Container& __x)
| ^
2 errors generated.
Compiler returned: 1
If I remove the _cf
literal operator, it works fine. It also works if I rewrite it with format_as
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4