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

fmt 11 cannot format string_view #4180

Closed
aminya opened this issue Oct 1, 2024 · 2 comments
Closed

fmt 11 cannot format string_view #4180

aminya opened this issue Oct 1, 2024 · 2 comments
Labels

Comments

@aminya
Copy link
Contributor

aminya commented Oct 1, 2024

I updated the following code to fmt 11, and it no longer compiles with the below error. Do you know what could be the reason?

Unfortunately, I can't reproduce it on Godbolt, but here's the link anyway. I included all the calls to the function. My suspect is that other libraries or headers break fmt.
https://godbolt.org/z/Gvabcz5Ex

#include <fmt/core.h>
#include <stdexcept>

#include <string>
#include <string_view>

using std::string_view, std::exception, std::runtime_error, std::string;

[[noreturn]] inline void print_string_view(string_view message) {
  fmt::print(stderr, "{}\n", message);
}


int main() {
    try {
        throw runtime_error("test");
    } catch (const exception& err) {
        print_string_view(err.what());
    }

    print_string_view("sss" + string("sss"));
}
build/vcpkg_installed/x64-linux/include/fmt/base.h:1518:68: error: no matching member function for call to 'map'
 1518 |   FMT_MAP_API auto map(const T& val) -> decltype(FMT_DECLTYPE_THIS map(U())) {
      |                                                                    ^~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1560:28: note: in instantiation of template class 'fmt::detail::arg_mapper<fmt::context>' requested here
 1560 |     type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())),
      |                            ^
build/vcpkg_installed/x64-linux/include/fmt/base.h:2733:16: note: in instantiation of template type alias 'mapped_type_constant' requested here
 2733 |       : types_{mapped_type_constant<Args, buffered_context<Char>>::value...},
      |                ^
build/vcpkg_installed/x64-linux/include/fmt/base.h:2884:47: note: in instantiation of member function 'fmt::detail::format_string_checker<char, std::basic_string_view<char>>::format_string_checker' requested here
 2884 |       detail::parse_format_string<true>(str_, checker(s));
      |                                               ^
packages/stdx/include/stdx/errors.hpp:18:22: note: in instantiation of function template specialization 'fmt::basic_format_string<char, std::basic_string_view<char> &>::basic_format_string<char[4], 0>' requested here
   18 |   fmt::print(stderr, "{}\n", message);
      |                      ^
build/vcpkg_installed/x64-linux/include/fmt/base.h:1511:20: note: candidate function template not viable: requires single argument 'values', but no arguments were provided
 1511 |   FMT_MAP_API auto map(const T (&values)[N]) -> const T (&)[N] {
      |                    ^   ~~~~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1505:22: note: candidate function template not viable: requires 1 argument, but 0 were provided
 1505 |   FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer {
      |                      ^   ~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1494:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1494 |   FMT_MAP_API auto map(std::nullptr_t val) -> const void* { return val; }
      |                    ^   ~~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1491:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1491 |   FMT_MAP_API auto map(const volatile void* val) -> const void* {
      |                    ^   ~~~~~~~~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1488:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1488 |   FMT_MAP_API auto map(volatile void* val) -> const void* {
      |                    ^   ~~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1487:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1487 |   FMT_MAP_API auto map(const void* val) -> const void* { return val; }
      |                    ^   ~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1486:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1486 |   FMT_MAP_API auto map(void* val) -> const void* { return val; }
      |                    ^   ~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1482:20: note: candidate function template not viable: requires 1 argument, but 0 were provided
 1482 |   FMT_MAP_API auto map(const T&) -> unformattable_char {
      |                    ^   ~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1476:20: note: candidate function template not viable: requires single argument 'val', but no arguments were provided
 1476 |   FMT_MAP_API auto map(const T& val) -> basic_string_view<Char> {
      |                    ^   ~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1472:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1472 |   FMT_MAP_API auto map(const char_type* val) -> const char_type* { return val; }
      |                    ^   ~~~~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1471:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1471 |   FMT_MAP_API auto map(char_type* val) -> const char_type* { return val; }
      |                    ^   ~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1469:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1469 |   FMT_MAP_API auto map(long double val) -> long double { return val; }
      |                    ^   ~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1468:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1468 |   FMT_MAP_API auto map(double val) -> double { return val; }
      |                    ^   ~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1467:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1467 |   FMT_MAP_API auto map(float val) -> float { return val; }
      |                    ^   ~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1463:20: note: candidate function template not viable: requires 1 argument, but 0 were provided
 1463 |   FMT_MAP_API auto map(T) -> unformattable_char {
      |                    ^   ~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1452:20: note: candidate function template not viable: requires single argument 'val', but no arguments were provided
 1452 |   FMT_MAP_API auto map(T val) -> char_type {
      |                    ^   ~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1448:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1448 |   FMT_MAP_API auto map(bool val) -> bool { return val; }
      |                    ^   ~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1447:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1447 |   FMT_MAP_API auto map(uint128_opt val) -> uint128_opt { return val; }
      |                    ^   ~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1446:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1446 |   FMT_MAP_API auto map(int128_opt val) -> int128_opt { return val; }
      |                    ^   ~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1443:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1443 |   FMT_MAP_API auto map(unsigned long long val) -> unsigned long long {
      |                    ^   ~~~~~~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1442:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1442 |   FMT_MAP_API auto map(long long val) -> long long { return val; }
      |                    ^   ~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1441:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1441 |   FMT_MAP_API auto map(unsigned long val) -> ulong_type { return val; }
      |                    ^   ~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1440:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1440 |   FMT_MAP_API auto map(long val) -> long_type { return val; }
      |                    ^   ~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1439:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1439 |   FMT_MAP_API auto map(unsigned val) -> unsigned { return val; }
      |                    ^   ~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1438:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1438 |   FMT_MAP_API auto map(int val) -> int { return val; }
      |                    ^   ~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1437:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1437 |   FMT_MAP_API auto map(unsigned short val) -> unsigned { return val; }
      |                    ^   ~~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1436:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1436 |   FMT_MAP_API auto map(short val) -> int { return val; }
      |                    ^   ~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1435:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1435 |   FMT_MAP_API auto map(unsigned char val) -> unsigned { return val; }
      |                    ^   ~~~~~~~~~~~~~~~~~
build/vcpkg_installed/x64-linux/include/fmt/base.h:1434:20: note: candidate function not viable: requires single argument 'val', but no arguments were provided
 1434 |   FMT_MAP_API auto map(signed char val) -> int { return val; }
      |                    ^   ~~~~~~~~~~~~~~~
1 error generated.
@aminya
Copy link
Contributor Author

aminya commented Oct 1, 2024

Okay, I found the reason. It's cpprest headers. Including fmt after cpprest causes these issues.

Cpprest does some questionable macro definitions here.
https://github.com/microsoft/cpprestsdk/blob/411a109150b270f23c8c97fa4ec9a0a4a98cdecf/Release/include/cpprest/details/basic_types.h#L87

The U Macro overrides the U typename in fmt!!

  template <typename T, typename U = format_as_t<T>,
            FMT_ENABLE_IF(std::is_arithmetic<U>::value)>
  FMT_MAP_API auto map(const T& val) -> decltype(FMT_DECLTYPE_THIS map(U())) {
    return map(format_as(val));
  }

I think we have to make a PR to fix this upstream.

As a workaround _TURN_OFF_PLATFORM_STRING can be defined before including cpprest headers.

@aminya
Copy link
Contributor Author

aminya commented Oct 2, 2024

A better workaround is to undef U after including any headers that include cpprest

// include some header that includes cpprest
// immediately after:
#if defined(U)
#undef U
#endif

This applies to any client generated by OpenAPI

https://github.com/OpenAPITools/openapi-generator/blob/673cd15e72d8dc110bcb685a36a4e0b4c8dfe67c/modules/openapi-generator/src/main/resources/cpp-rest-sdk-client/model-source.mustache#L83

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants