从 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"
。
#
是否应该将 0x
算作宽度的一部分? (如果我删除它,我会按预期得到 8 个半字节)
有没有更好的方法来制定这个格式字符串,没有 sizeof 东西?
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;
}
我正在试验新的 C++ 2020 std::format
函数。我想用从其类型推导出的宽度来表示输出。目前我有这条线:
std::wstring wstr = std::format( L"{0:#0{1}x}", ::GetLastError(), sizeof( ::GetLastError() ) * 2 );
这导致值 L"0x000002"
。
#
是否应该将0x
算作宽度的一部分? (如果我删除它,我会按预期得到 8 个半字节)有没有更好的方法来制定这个格式字符串,没有 sizeof 东西?
Is
#
supposed to count the0x
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;
}