fmtlib / fmt

A modern formatting library
https://fmt.dev
Other
19.83k stars 2.42k forks source link

Not compiled std::vector<bool> as a range #4026

Closed dmyger closed 2 weeks ago

dmyger commented 2 weeks ago

MacOS AppleClang++ 15; LLVM Clang++ 18 Conan v2

Can't compile following code with latest 10.2.1 version of library. While with 9.1.0 - it works as expected.

#include <cassert>
#include <vector>
#include <fmt/core.h>
#include <fmt/ranges.h>

int main()
{
    const std::vector<bool> vec{true, false};
    assert(fmt::format("{}", vec) == "[true, false]");
}
Compile errors ``` [build] Starting build [proc] Executing command: /usr/local/bin/cmake --build src/test/Clang=Debug --config Debug --target tst_fmt -- [build] [1/2 50% :: 1.853] Building CXX object CMakeFiles/tst_fmt.dir/tst_fmt.cpp.o [build] FAILED: CMakeFiles/tst_fmt.dir/tst_fmt.cpp.o [build] /usr/bin/clang++ -DFMT_HEADER_ONLY=1 -isystem .conan2/p/fmt973b15748dcf1/p/include -g -std=gnu++20 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -Wall -MD -MT CMakeFiles/tst_fmt.dir/tst_fmt.cpp.o -MF CMakeFiles/tst_fmt.dir/tst_fmt.cpp.o.d -o CMakeFiles/tst_fmt.dir/tst_fmt.cpp.o -c src/test/tst_fmt.cpp [build] In file included from src/test/tst_fmt.cpp:3: [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:2593:45: error: implicit instantiation of undefined template 'fmt::detail::type_is_unformattable_for, char>' [build] type_is_unformattable_for _; [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:2656:23: note: in instantiation of function template specialization 'fmt::detail::parse_format_specs, fmt::detail::compile_parse_context>' requested here [build] parse_funcs_{&parse_format_specs...} {} [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:2787:47: note: in instantiation of member function 'fmt::detail::format_string_checker>::format_string_checker' requested here [build] detail::parse_format_string(str_, checker(s)); [build] ^ [build] src/test/tst_fmt.cpp:9:24: note: in instantiation of function template specialization 'fmt::basic_format_string &>::basic_format_string' requested here [build] assert(fmt::format("{}", vec) == "[true, false]"); [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:1578:45: note: template is declared here [build] template struct type_is_unformattable_for; [build] ^ [build] src/test/tst_fmt.cpp:9:24: error: call to consteval function 'fmt::basic_format_string &>::basic_format_string' is not a constant expression [build] assert(fmt::format("{}", vec) == "[true, false]"); [build] ^ [build] In file included from src/test/tst_fmt.cpp:3: [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:1600:63: error: implicit instantiation of undefined template 'fmt::detail::type_is_unformattable_for, char>' [build] type_is_unformattable_for _; [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:1842:23: note: in instantiation of function template specialization 'fmt::detail::make_arg, const std::vector, 0>' requested here [build] data_{detail::make_arg(args)...} { [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:1860:10: note: in instantiation of function template specialization 'fmt::format_arg_store, std::vector>::format_arg_store>' requested here [build] return {args...}; [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:2835:28: note: in instantiation of function template specialization 'fmt::make_format_args, const std::vector>' requested here [build] return vformat(fmt, fmt::make_format_args(args...)); [build] ^ [build] src/test/tst_fmt.cpp:9:17: note: in instantiation of function template specialization 'fmt::format &>' requested here [build] assert(fmt::format("{}", vec) == "[true, false]"); [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:1578:45: note: template is declared here [build] template struct type_is_unformattable_for; [build] ^ [build] .conan2/p/fmt973b15748dcf1/p/include/fmt/core.h:1603:3: error: static assertion failed due to requirement 'formattable': Cannot format an argument. To make type T formattable provide a formatter specialization: https://fmt.dev/latest/api.html#udt [build] static_assert( [build] ^ [build] 4 errors generated. ```
phprus commented 2 weeks ago

Try adding a header:

#include <fmt/std.h>
vitaut commented 2 weeks ago

As @phprus already mentioned above you need to include fmt/std.h. Among other things, this header provides a formatter for the proxy type used by vector<bool>. More generally, for a range to be formattable its elements also have to be formattable.

dmyger commented 2 weeks ago
#include <fmt/std.h>

Thank you. It's helps.

It would be great to have something similar in your test cases. While I see that in std-test.cc only by elements is tested, not the whole container.