从 std::format 中的数据类型推断字段宽度

Deduce field width from data type in std::format

我正在试验新的 C++ 2020 std::format 函数。我想用从其类型推导出的宽度来表示输出。目前我有这条线:

std::wstring wstr = std::format( L"{0:#0{1}x}", ::GetLastError(), sizeof( ::GetLastError() ) * 2 );

这导致值 L"0x000002"

Is # supposed to count the 0x as part of the width? (If I remove it, I get 8 nibbles as expected)

是的。 [format.string.std]/13 中有一个示例说明了这一点。整个字符串是6个字符,包括0x:

string s2 = format("{:#06x}", 0xa);     // value of s2 is "0x000a"

这类似于 printf 所做的。

Is there a better way of formulating this format string, without sizeof thing?

如果这是您想经常做的事情,那么您可以创建自己的类型并在内部定义其格式,以便您只需编写:

std::wstring wstr = std::format( L"{}", PrettyHex{::GetLastError()});

但这只是移动 sizeof 发生的地方 - 您仍然需要在某个地方手动提供它,这里没有捷径。

反正我写了这个专业。所以如果有人感兴趣,这里是:

#include <format>
#include <iostream>

typedef unsigned long DWORD;

struct PrettyHex {
    DWORD dwValue;
};

template<>
struct std::formatter< PrettyHex, wchar_t > : std::formatter< std::wstring, wchar_t > {
    auto format( PrettyHex prettyHex, std::wformat_context& context ) {
        std::wstring wstrPrettyHex = std::format( L"0x{:0{}x}", prettyHex.dwValue, sizeof prettyHex.dwValue * 2 );
        return std::formatter< std::wstring, wchar_t >::format( wstrPrettyHex, context );
    }
};

int wmain() {
    DWORD dwTest = 102;
    std::wstring wstrTest = std::format( L"dwTest formatted as DWORD: {}\ndwTest formatted as PrettyHex: {}\n", dwTest, PrettyHex{ dwTest } );
    std::wcout << wstrTest;

    return 0;
}