Skip to content
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

new compilation error by upgrading from 11.0.1 to 11.1.2 with std::ostreambuf_iterator #4309

Closed
lano1106 opened this issue Jan 15, 2025 · 4 comments

Comments

@lano1106
Copy link

In file included from /usr/include/fmt/chrono.h:23,
                 from time_util.cpp:11:
/usr/include/fmt/format.h: In instantiation of ‘constexpr OutputIt fmt::v11::detail::write(OutputIt, T) [with Char = char; OutputIt = std::ostreambuf_iterator<char, std::char_traits<char> >; T = long int; typename std::enable_if<((is_integral<T>::value && (! std::is_same<T, bool>::value)) && (! std::is_same<T, Char>::value)), int>::type <anonymous> = 0]’:
/usr/include/fmt/compile.h:169:25:   required from ‘constexpr OutputIt fmt::v11::detail::field<Char, T, N>::format(OutputIt, const Args& ...) const [with OutputIt = std::ostreambuf_iterator<char, std::char_traits<char> >; Args = {long int, long int}; Char = char; T = long int; int N = 0]’
  169 |       return write<Char>(out, arg);
      |              ~~~~~~~~~~~^~~~~~~~~~
/usr/include/fmt/compile.h:234:21:   required from ‘constexpr OutputIt fmt::v11::detail::concat<L, R>::format(OutputIt, const Args& ...) const [with OutputIt = std::ostreambuf_iterator<char, std::char_traits<char> >; Args = {long int, long int}; L = fmt::v11::detail::field<char, long int, 0>; R = fmt::v11::detail::concat<fmt::v11::detail::code_unit<char>, fmt::v11::detail::spec_field<char, long int, 1> >]’
  234 |     out = lhs.format(out, args...);
      |           ~~~~~~~~~~^~~~~~~~~~~~~~
/usr/include/fmt/compile.h:460:19:   required from ‘constexpr OutputIt fmt::v11::format_to(OutputIt, const CompiledFormat&, const Args& ...) [with OutputIt = std::ostreambuf_iterator<char, std::char_traits<char> >; CompiledFormat = detail::concat<detail::field<char, long int, 0>, detail::concat<detail::code_unit<char>, detail::spec_field<char, long int, 1> > >; Args = {long int, long int}; typename std::enable_if<detail::is_compiled_format<CompiledFormat>::value, int>::type <anonymous> = 0]’
  460 |   return cf.format(out, args...);
      |          ~~~~~~~~~^~~~~~~~~~~~~~
/usr/include/fmt/compile.h:500:26:   required from ‘constexpr OutputIt fmt::v11::format_to(OutputIt, const S&, Args&& ...) [with OutputIt = std::ostreambuf_iterator<char, std::char_traits<char> >; S = detail::udl_compiled_string<char, 10, detail::fixed_string<char, 10>{"{}.{:06d}"}>; Args = {const long int&, const long int&}; typename std::enable_if<detail::is_compiled_string<S>::value, int>::type <anonymous> = 0]’
  500 |     return fmt::format_to(out, compiled, std::forward<Args>(args)...);
      |            ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
time_util.cpp:63:19:   required from here
   63 |     fmt::format_to(std::ostreambuf_iterator<char>{o}, "{}.{:06d}"_cf,
      |     ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   64 |                ts.tv_sec, ts.tv_usec);
      |                ~~~~~~~~~~~~~~~~~~~~~~
/usr/include/fmt/format.h:2168:30: error: no matching function for call to ‘format_decimal<char>(std::ostreambuf_iterator<char, std::char_traits<char> >&, long unsigned int&, int&)’
 2168 |   return format_decimal<Char>(out, abs_value, num_digits);
      |          ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/fmt/format.h:1199:31: note: candidate: ‘template<class Char, class UInt> constexpr Char* fmt::v11::detail::format_decimal(Char*, UInt, int)’
 1199 | FMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value,
      |                               ^~~~~~~~~~~~~~
/usr/include/fmt/format.h:1199:31: note:   template argument deduction/substitution failed:
/usr/include/fmt/format.h:2168:31: note:   cannot convert ‘out’ (type ‘std::ostreambuf_iterator<char, std::char_traits<char> >’) to type ‘char*’
 2168 |   return format_decimal<Char>(out, abs_value, num_digits);
      |                               ^~~
/usr/include/fmt/format.h:1207:20: note: candidate: ‘template<class Char, class UInt, class OutputIt, typename std::enable_if<fmt::v11::detail::is_back_insert_iterator<OutputIt>::value, int>::type <anonymous> > constexpr OutputIt fmt::v11::detail::format_decimal(OutputIt, UInt, int)’
 1207 | FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits)
      |                    ^~~~~~~~~~~~~~
/usr/include/fmt/format.h:1207:20: note:   template argument deduction/substitution failed:
In file included from /usr/include/fmt/format.h:41:
/usr/include/fmt/format.h:1206:11: error: no type named ‘type’ in ‘struct std::enable_if<false, int>’
 1206 |           FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
      |           ^~~~~~~~~~~~~
make: *** [Makefile:64: time_util.o] Error 1

I have locally fixed the problem by changing the fmt/formt.h template declaration from:

template <typename Char, typename UInt, typename OutputIt,
          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>
FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits)
    -> OutputIt {

to

template <typename Char, typename UInt, typename OutputIt>
FMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits)
    -> OutputIt {
@vitaut
Copy link
Contributor

vitaut commented Jan 15, 2025

Please provide a godbolt repro.

@lano1106
Copy link
Author

lano1106 commented Jan 16, 2025

I am not sure why you need a godbolt repro... with my explanations, it is pretty obvious what is happening.
the format_decimal() template function is not enabled because std::ostreambuf_iterator is an output iterator and not a back_inserter_iterator.

format_decimal() does not need the iterator to be a back_inserter_iterator for the template function to work perfectly. I did not go as far as looking how it was done in 11.0.1 but I suspect that FMT_ENABLE_IF(is_back_insert_iterator::value) is an addition to 11.1

beside that, you made an excellent job in this new release by eliminating all those annoying linker warnings...

@phprus
Copy link
Contributor

phprus commented Jan 16, 2025

Maybe fixed by #4312

@lano1106
Copy link
Author

lano1106 commented Jan 16, 2025

by visual inspection, I would say that it does... I am just curious to know what the enable_if statement accomplish....

imho, it would be nice to document in a small comment...

I have solved my problem by totally removing it not knowing what was its purpose. It did not seem like the other format_decimal() overload presence could create any ambiguity for the compiler to choose which one to take...

@vitaut vitaut closed this as completed Jan 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants