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>.
如果 typename Context::template formatter_type<std::remove_const_t<Ti>> 不满足 BasicFormatter 要求,则行为未定义,其中 Ti
属于 Args
中的任何类型。
如果 Args
中的任何类型 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 存储一个 std::basic_format_arg<Context>::handle 到
t
,以及handle::format()
所需的额外数据。
[edit] 说明
格式化参数对用户定义类型具有引用语义,并且不会延长 args 的生命周期。程序员有责任确保 args 超过返回值的生命周期。通常,结果仅用作格式化函数的参数。
功能测试 宏 | 值 | Std | 功能 |
---|---|---|---|
__cpp_lib_format_uchar |
202311L | (C++20) (DR) |
将代码单元格式化为无符号整数 |
[edit] 示例
运行此代码
#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) { // Generate formatting string "{} "... 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
[edit] 缺陷报告
以下行为更改缺陷报告已追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布的行为 | 正确行为 |
---|---|---|---|
P2418R2 | C++20 | 既不是常量可使用也不是可复制的对象 (例如生成器类对象) 不可格式化 |
允许格式化这些对象 |
P2905R2 | C++20 | make_format_args 通过转发引用接受右值参数 |
仅接受左值引用 |
P2909R4 | C++20 | char 或 wchar_t 可能被格式化为 超出范围的无符号整数值 |
代码单元在进行此类格式化之前会转换为相应的 无符号类型 |
LWG 3631 | C++20 | 在 P2418R2 之后,cv 限定参数处理不正确 | 处理已修正 |
[edit] 另请参阅
(C++20)(C++20)(C++20) |
提供对所有格式化参数访问的类 (类模板) |
(C++20) |
使用类型擦除参数表示的 std::format 的非模板变体 (函数) |
(C++20) |
使用类型擦除参数表示的 std::format_to 的非模板变体 (函数模板) |