Issue |
138662
|
Summary |
Clang fails to build code involving custom range and format [C++23, std::format, std::ranges]
|
Labels |
clang
|
Assignees |
|
Reporter |
h-2
|
There is a custom string-class and a formatter that delegates to string_view's formatter. If the latter is disabled, the default formatter for string is chosen.
```cpp
#include <string_view>
#include <format>
#include <print>
#include <ranges>
#include <tuple>
struct MyString
{
std::string_view s = "foo";
char const * begin() noexcept { return s.begin(); }
char const * end() noexcept { return s.end(); }
std::string_view asStringView() const noexcept
{
return s;
}
};
static_assert(std::ranges::random_access_range<MyString>);
#if 0 // TURN ME ON
template <>
struct std::formatter<MyString> : std::formatter<std::string_view>
{
auto format(MyString const & s, std::format_context& ctx) const
{
return std::formatter<std::string_view>::format(s.asStringView(), ctx);
}
};
#endif
int main()
{
MyString s;
std::println("{}", s);
std::tuple<MyString> tup{};
#if 1 // TURN ME ON
std::println("{}", tup);
#endif
}
```
[godbolt](https://godbolt.org/z/7P88c748T)
By default, the code builds (Clang-20.1 with libc++ and c++23) and prints the following:
```
['f', 'o', 'o']
(['f', 'o', 'o'])
```
This is expected. Since the custom formatter is disabled, the generic range protocol ("every character individually") is chosen. In the second case, the tuple protocol (parens) is applied first, then the generic range protocol.
If we turn the custom formatter on, the first print statement prints `foo` because we switch to "string protocol". However, the second print statement does not build, because supposedly the type is not formattable.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs