std::format_to_n, std::format_to_n_result

来自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 OutputIt, class... Args >

std::format_to_n_result<OutputIt>
    format_to_n( OutputIt out, std::iter_difference_t<OutputIt> n,

                 std::format_string<Args...> fmt, Args&&... args );
(1) (C++20 起)
template< class OutputIt, class... Args >

std::format_to_n_result<OutputIt>
    format_to_n( OutputIt out, std::iter_difference_t<OutputIt> n,

                 std::wformat_string<Args...> fmt, Args&&... args );
(2) (C++20 起)
template< class OutputIt, class... Args >

std::format_to_n_result<OutputIt>
    format_to_n( OutputIt out, std::iter_difference_t<OutputIt> n,
                 const std::locale& loc,

                 std::format_string<Args...> fmt, Args&&... args );
(3) (C++20 起)
template< class OutputIt, class... Args >

std::format_to_n_result<OutputIt>
    format_to_n( OutputIt out, std::iter_difference_t<OutputIt> n,
                 const std::locale& loc,

                 std::wformat_string<Args...> fmt, Args&&... args );
(4) (C++20 起)
Helper types
template< class OutputIt >

struct format_to_n_result {
    OutputIt out;
    std::iter_difference_t<OutputIt> size;

};
(5) (C++20 起)

按照格式字符串 fmt 格式化 args,并将结果写入到输出迭代器 out。至多写 n 个字符。 loc 若存在则用于本地环境特定的格式化。

CharT 对于重载 (1,3)char,对于重载 wchar_t(2,4)

这些重载只有在 OutputIt 满足概念 std::output_iterator<const CharT&> 时才会参与重载决议。若 OutputIt 不实现(满足其语义要求)概念 std::output_iterator<const CharT&>,或若对 Args 中任何 Tistd::formatter<Ti, CharT> 不满足格式化器 (Formatter) 要求,则其行为未定义。

5) std::format_to_n_result 无基类或 outsize 及隐式声明的特殊成员函数以外的成员。

参数

out - 指向输出缓冲区的迭代器
n - 写入输出缓冲区的最大字符数
fmt - 用于表示格式字符串的对象。格式字符串由以下组成
  • 通常字符(除了 {}),它们被不加修改地复制到输出,
  • 转义序列 {{}} ,它们在输出中被分别替换成 {} ,以及
  • 替换域。

每个替换域拥有如下格式:

{ 实参索引 (可选) } (1)
{ 实参索引 (可选) : 格式说明 } (2)
1) 没有格式说明的替换域
2) 有格式说明的替换域
实参索引 - 指定用于格式化它的值的 args 中的参数的下标;如果省略实参索引,那么按顺序使用参数。

格式字符串中的实参索引 必须全部存在或全部被省略。混合手动和自动指定下标是错误。

格式说明 - 格式说明由对应参数特化的 std::formatter 定义。不能以 } 开始。

(C++23 起)
(C++26 起)
  • 对于其他可格式化类型,格式说明由用户定义的 std::formatter 特化决定。
args... - 要格式化的实参
loc - 用于本地环境特定的格式化的 std::locale

返回值

format_to_n_result,其 out 成员为指向输出范围末尾后一位置的迭代器,而 size 成员为总(不截断)的输出大小。

异常

传播格式化器或迭代器操作所抛的任何异常。

注解

GCC-13.3 之前的 libstdc++ 实现在报告正确的 format_to_n_result::out 值时存在 bug

示例

Godbolt Compiler Explorer: clang (trunk) + libc++, GCC (trunk) + libstdc++.

#include <format>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <string_view>
 
int main()
{
    char buffer[64];
 
    for (std::size_t max_chars_to_write : {std::size(buffer) - 1, 23uz, 21uz})
    {
        const std::format_to_n_result result =
            std::format_to_n(
                buffer, max_chars_to_write,
                "Hubble's H{2} {3} {0}{4}{1} km/sec/Mpc.", // 格式化之外有 24 个字节
                71,       // {0}, 占据 2 个字节
                8,        // {1}, 占据 1 个字节
                "\u2080", // {2}, 占据 3 个字节, '₀' (SUBSCRIPT ZERO)
                "\u2245", // {3}, 占据 3 个字节, '≅' (APPROXIMATELY EQUAL TO)
                "\u00B1"  // {4}, 占据 2 个字节, '±' (PLUS-MINUS SIGN)
                ); // 24 + 2 + 1 + 3 + 3 + 2 == 35, 没有末尾 '\0'
 
        *result.out = '\0'; // 向缓冲区添加终止符
 
        const std::string_view str(buffer, result.out);
 
        std::cout << "'\\0' 前的缓冲区: " << std::quoted(str) << '\n'
                  << "最大写入字符数: " << max_chars_to_write << '\n'
                  << "result.out 偏移量: " << result.out - buffer << '\n'
                  << "未截断的输出大小: " << result.size << "\n\n";
    }
}

输出:

'\0' 前的缓冲区: "Hubble's H₀ ≅ 71±8 km/sec/Mpc."
最大写入字符数: 63
result.out 偏移量: 35
未截断的输出大小: 35
 
'\0' 前的缓冲区: "Hubble's H₀ ≅ 71±8"
最大写入字符数: 23
result.out 偏移量: 23
未截断的输出大小: 35
 
'\0' 前的缓冲区: "Hubble's H₀ ≅ 71�"
最大写入字符数: 21
result.out 偏移量: 21
未截断的输出大小: 35

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
P2216R3 C++20 对非法格式字符串抛出 std::format_error 非法格式字符串导致编译时错误
P2418R2 C++20 无法格式化既非 const 可用也不可复制的对象(如生成器式对象) 允许格式化这些对象
P2508R1 C++20 这个设施没有用户可见的名字 暴露出 basic_format_string 的名字

参阅

(C++20)
在新字符串中存储参数的格式化表示
(函数模板)
(C++20)
通过输出迭代器写入其实参的格式化表示
(函数模板)
确定存储其参数的格式化表示所需的字符数
(函数模板)