-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
We reject this correct program (https://godbolt.org/z/MhWWYa3P7):
#include <format>
#include <string>
#include <string_view>
struct mytraits : std::char_traits<char> {};
int main() {
(void) std::format("{}", std::basic_string_view<char, mytraits>{});
}with an error complaining that static_cast can't convert from the argument type to std::string_view in _Format_arg_store::_Store:
Line 1881 in 8ddf4da
| _Store_impl<_Erased_type>(_Arg_index, _Arg_type, static_cast<_Erased_type>(_Val)); |
The static_cast would trigger the basic_string_view converting constructor that takes contiguous ranges were it not for [string.view.cons]/12.6: "if the qualified-id remove_reference_t<R>::traits_type is valid and denotes a type, is_same_v<remove_reference_t<R>::traits_type, traits> is true". This constraint rejects conversions between specializations of basic_string_view with the same element type but differing traits types.
The obvious fix is to change the standard (and <xstring>) to remove that constraint so the static_cast in <format> works. I've reached out to WG21 to suggest that this constraint made sense when the constructor was implicit, but doesn't now that the it is explicit. I received quite a bit of support for and no opposition to striking the constraint.
We need to file an LWG issue to make the change, and speculatively implement the proposed resolution.