Consider the following example of formatting to a fixed size buffer before writing to stdout:
#include <fmt/format.h>
#include <unistd.h>
void vlog(fmt::string_view format, fmt::format_args args) {
char line[1024];
auto [_, size] = fmt::vformat_to_n(line, sizeof(line), format, args);
write(STDOUT_FILENO, line, size);
}
template <typename S, typename... Args>
void log(const S& format, Args&&... args) {
vlog(format, fmt::make_args_checked<Args...>(format, args...));
}
int main() {
log("invalid squishiness: {}", 42);
}
<source>: In function 'void vlog(fmt::v7::string_view, fmt::v7::format_args)':
<source>:6:70: error: no matching function for call to 'vformat_to_n(char [1024], long unsigned int, fmt::v7::string_view&, fmt::v7::format_args&)'
auto [_, size] = fmt::vformat_to_n(line, sizeof(line), format, args);
^
In file included from /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:46,
from <source>:1:
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1830:37: note: candidate: 'template<class OutputIt, class Char, class ... Args, typename std::enable_if<fmt::v7::detail::is_output_iterator<OutputIt, Char>::value, int>::type <anonymous> > fmt::v7::format_to_n_result<OutputIt> fmt::v7::vformat_to_n(OutputIt, size_t, fmt::v7::basic_string_view<Char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<typename fmt::v7::type_identity<Char>::type>, typename fmt::v7::type_identity<Char>::type> >)'
inline format_to_n_result<OutputIt> vformat_to_n(
^~~~~~~~~~~~
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1830:37: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1829:11: error: no type named 'type' in 'struct std::enable_if<false, int>'
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
^~~~~~~~~~~~~
ASM generation compiler returned: 1
<source>: In function 'void vlog(fmt::v7::string_view, fmt::v7::format_args)':
<source>:6:70: error: no matching function for call to 'vformat_to_n(char [1024], long unsigned int, fmt::v7::string_view&, fmt::v7::format_args&)'
auto [_, size] = fmt::vformat_to_n(line, sizeof(line), format, args);
^
In file included from /opt/compiler-explorer/libs/fmt/trunk/include/fmt/format.h:46,
from <source>:1:
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1830:37: note: candidate: 'template<class OutputIt, class Char, class ... Args, typename std::enable_if<fmt::v7::detail::is_output_iterator<OutputIt, Char>::value, int>::type <anonymous> > fmt::v7::format_to_n_result<OutputIt> fmt::v7::vformat_to_n(OutputIt, size_t, fmt::v7::basic_string_view<Char>, fmt::v7::basic_format_args<fmt::v7::basic_format_context<fmt::v7::detail::buffer_appender<typename fmt::v7::type_identity<Char>::type>, typename fmt::v7::type_identity<Char>::type> >)'
inline format_to_n_result<OutputIt> vformat_to_n(
^~~~~~~~~~~~
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1830:37: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1829:11: error: no type named 'type' in 'struct std::enable_if<false, int>'
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value)>
^~~~~~~~~~~~~
Unfortunately GCC 8 is still relevant to me as it is the most recent upstream-built compiler for Red Hat / CentOS 6 (via devtoolset-8).
Consider the following example of formatting to a fixed size buffer before writing to stdout:
With GCC 9 and 10 this works. But with GCC 8 this fails to compile (godbolt) with:
Unfortunately GCC 8 is still relevant to me as it is the most recent upstream-built compiler for Red Hat / CentOS 6 (via devtoolset-8).