std::make_format_args, std::make_wformat_args
来自cppreference.com
在标头 <format> 定义
|
||
template< class Context = std::format_context, class... Args > /*format-arg-store*/<Context, Args...> |
(1) | (C++20 起) |
template< class... Args > /*format-arg-store*/<std::wformat_context, Args...> |
(2) | (C++20 起) |
返回存储格式化参数的数组,并能隐式转换为 std::basic_format_args<Context> 的对象。
若对于 Args
中的任一 Ti
,typename Context::template formatter_type<std::remove_const_t<Ti>> 不符合基本格式化器 (BasicFormatter) 要求,则行为未定义。
若对于 Args
中的任一 Ti
,Ti
不满足 __formattable_with<Context> 则程序非良构。
2) 等价于 return std::make_format_args<std::wformat_context>(args...);。
参数
args... | - | 用作格式化参数的值 |
返回值
保有格式化参数的对象。
对于每个 T
类型的参数 t
,令 TD
为 std::remove_const_t<std::remove_reference_t<T>>。结果中对应的 std::basic_format_arg 以如下方式确定:
- 若
TD
为 bool 或Context::char_type
,则 std::basic_format_arg 存储 t; - 否则,若
TD
为 char 且Context::char_type
为 wchar_t,则 std::basic_format_arg 存储 static_cast<wchar_t>(static_cast<unsigned char>(t)); - 否则,若
TD
为大小不大于 int 的有符号整数类型,则 std::basic_format_arg 存储 static_cast<int>(t); - 否则,若
TD
为大小不大于 unsigned int 的无符号整数类型,则 std::basic_format_arg 存储 static_cast<unsigned int>(t); - 否则,若
TD
为大小不大于 long long 的有符号整数类型,则 std::basic_format_arg 存储 static_cast<long long>(t); - 否则,若
TD
为大小不大于 unsigned long long 的无符号整数类型,则 std::basic_format_arg 存储 static_cast<unsigned long long>(t); - 否则,若
TD
为 float、double 或 long double,则 std::basic_format_arg 存储 t; - 否则,若
TD
为 std::basic_string_view 或 std::basic_string 的特化且TD::char_type
为Context::char_type
,则 std::basic_format_arg 存储 std::basic_string_view<Context::char_type>(t.data(), t.size()); - 否则,若 std::decay_t<TD> 为 Context::char_type* 或 const Context::char_type*,则 std::basic_format_arg 存储 static_cast<const Context::char_type*>(t);
- 否则,若 std::is_void_v<std::remove_pointer_t<TD>> 为 true 或 std::is_null_pointer_v<TD> 为 true,则 std::basic_format_arg 存储 static_cast<const void*>(t);
- 否则,std::basic_format_arg 存储指向
t
并且携带handle::format()
所需的额外数据的 std::basic_format_arg<Context>::handle。
注解
对于用户定义类型,格式化参数拥有引用语义并且不延长其生存期。程序员负责确保该参数存活得比返回值更久。通常结果仅在格式化函数内使用。
功能特性测试宏 | 值 | 标准 | 功能特性 |
---|---|---|---|
__cpp_lib_format_uchar |
202311L | (C++20) (DR) |
格式化编码单元为无符号整数 |
示例
运行此代码
#include <array> #include <format> #include <iostream> #include <string_view> void raw_write_to_log(std::string_view users_fmt, std::format_args&& args) { static int n{}; std::clog << std::format("{:04} : ", n++) << std::vformat(users_fmt, args) << '\n'; } template<typename... Args> constexpr void log(Args&&... args) { // 生成格式化字符串 "{} " …… std::array<char, sizeof...(Args) * 3 + 1> braces{}; constexpr const char c[4] = "{} "; for (auto i{0uz}; i != braces.size() - 1; ++i) braces[i] = c[i % 3]; braces.back() = '\0'; raw_write_to_log(std::string_view{braces.data()}, std::make_format_args(args...)); } template<typename T> const T& unmove(T&& x) { return x; } int main() { log("Number", "of", "arguments", "is", "arbitrary."); log("Any type that meets the BasicFormatter requirements", "can be printed."); log("For example:", 1, 2.0, '3', "*42*"); raw_write_to_log("{:02} │ {} │ {} │ {}", std::make_format_args(unmove(1), unmove(2.0), unmove('3'), "4")); }
输出:
0000 : Number of arguments is arbitrary. 0001 : Any type that meets the BasicFormatter requirements can be printed. 0002 : For example: 1 2.0 3 *42* 0003 : 01 │ 2.0 │ 3 │ 4
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
P2418R2 | C++20 | 既非 const 可用亦非可复制的对象(例如 generator 式的对象)不可格式化
|
允许格式化这些对象 |
P2905R2 | C++20 | make_format_args 以转发引用接受右值参数
|
仅接收左值引用 |
P2909R4 | C++20 | char 或 wchar_t 可能被格式化为范围外的无符号整数值 | 在这种格式化前将编码单元转换为对应的无符号类型 |
LWG 3631 | C++20 | P2418R2 错误地处理了 cv 限定的参数 | 正确处理 |
参阅
(C++20)(C++20)(C++20) |
提供对所有格式化参数的访问的类 (类模板) |
(C++20) |
std::format 的使用类型擦除的参数表示的非模板变体 (函数) |
(C++20) |
std::format_to 的使用类型擦除的参数表示的非模板变体 (函数模板) |