microsoft / cppwinrt

C++/WinRT
MIT License
1.65k stars 238 forks source link

Feature: Support C++20 std::format for cppwinrt types (e.g. winrt::hstring) #1419

Closed dmachaj closed 4 months ago

dmachaj commented 4 months ago

Version

No response

Summary

std::format is a new C++ language feature that has some nice features for producing strings with data bound to them. It is possible to write std::formatter implementations that support additional types so that they can be natively used with std::format without requiring manual adaptation such as calling .c_str().

It would be nice if the various cppwinrt types, especially winrt::hstring had a formatter implementation so they work natively. Bonus points if things like winrt::hresult or winrt::hresult_error also could be printed easily.

Reproducible example

winrt::hstring myString{ L"MyString" };
std::format("My string is {0}", myString);

Expected behavior

Compiles and prints "My string is MyString"

Actual behavior

Build break

1>C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.40.33807\include\format(3567,23): error C2039: 'parse': is not a member of 'std::formatter<std::_Compile_time_parse_format_specs::_FormattedType,std::_Compile_time_parse_format_specs::_CharT>'
1>c:\source\repos\EmptyCppwinrtProgram\EmptyCppwinrtProgram\main.cpp(47,37): error C3615: consteval function 'std::_Compile_time_parse_format_specs' cannot result in a constant expression

Additional comments

No response

sylveon commented 4 months ago

There is a formatter for winrt::hstring already - however since hstrings are wide, you need a corresponding wide format string. This should work: std::format(L"My string is {0}", myString);

dmachaj commented 4 months ago

You're right. Not sure how I missed that 🤦.

I see this in <winrt/base.h>

#ifdef __cpp_lib_format
template<>
struct std::formatter<winrt::hstring, wchar_t> : std::formatter<std::wstring_view, wchar_t> {};
#endif