std::make_format_args, std::make_wformat_args

来自cppreference.com
< cpp‎ | utility‎ | format
 
 
工具库
语言支持
类型支持(基本类型、RTTI)
库功能特性测试宏 (C++20)
动态内存管理
程序工具
协程支持 (C++20)
变参数函数
调试支持
(C++26)
三路比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
初等字符串转换
(C++17)
(C++17)

 
 
在标头 <format> 定义
template< class Context = std::format_context, class... Args >

/*format-arg-store*/<Context, Args...>

    make_format_args( Args&... args );
(1) (C++20 起)
template< class... Args >

/*format-arg-store*/<std::wformat_context, Args...>

    make_wformat_args( Args&... args );
(2) (C++20 起)

返回存储格式化参数的数组,并能隐式转换为 std::basic_format_args<Context> 的对象。

若对于 Args 中的任一 Titypename Context::template formatter_type<std::remove_const_t<Ti>> 不符合基本格式化器 (BasicFormatter) 要求,则行为未定义。

若对于 Args 中的任一 TiTi 不满足 __formattable_with<Context> 则程序非良构。

2) 等价于 return std::make_format_args<std::wformat_context>(args...);

参数

args... - 用作格式化参数的值

返回值

保有格式化参数的对象。

对于每个 T 类型的参数 t,令 TDstd::remove_const_t<std::remove_reference_t<T>>。结果中对应的 std::basic_format_arg 以如下方式确定:

  • TDboolContext::char_type,则 std::basic_format_arg 存储 t
  • 否则,若 TDcharContext::char_typewchar_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)
  • 否则,若 TDfloatdoublelong double,则 std::basic_format_arg 存储 t
  • 否则,若 TDstd::basic_string_viewstd::basic_string 的特化且 TD::char_typeContext::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>>truestd::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 charwchar_t 可能被格式化为范围外的无符号整数值 在这种格式化前将编码单元转换为对应的无符号类型
LWG 3631 C++20 P2418R2 错误地处理了 cv 限定的参数 正确处理

参阅

提供对所有格式化参数的访问的类
(类模板)
(C++20)
std::format 的使用类型擦除的参数表示的非模板变体
(函数)
std::format_to 的使用类型擦除的参数表示的非模板变体
(函数模板)