format_formatted_size
format_formatted_size (형식화된 크기 계산)
std::formatted_size는 주어진 형식 문자열과 인자들을 사용해 형식화했을 때 생성될 문자열의 총 문자 수를 미리 계산하는 함수예요. 실제로 문자열을 만들지 않고 필요한 버퍼 크기만 알아내므로, 동적 버퍼를 할당하기 전에 정확한 크기를 확인할 때 유용해요. C++20부터 사용할 수 있어요.
출처: cppreference
본문
함수 개요
<format> 헤더에 정의되어 있어요.
| 정의 | 오버로드 | (since C++20) |
|---|---|---|
template<class... Args> std::size_t formatted_size(std::format_string<Args...> fmt, Args&&... args); |
(1) | (since C++20) |
template<class... Args> std::size_t formatted_size(std::wformat_string<Args...> fmt, Args&&... args); |
(2) | (since C++20) |
template<class... Args> std::size_t formatted_size(const std::locale& loc, std::format_string<Args...> fmt, Args&&... args); |
(3) | (since C++20) |
template<class... Args> std::size_t formatted_size(const std::locale& loc, std::wformat_string<Args...> fmt, Args&&... args); |
(4) | (since C++20) |
형식 문자열 fmt에 따라 args를 형식화하여 생성될 문자열의 총 문자 수를 결정해요. loc가 주어지면 로케일별 형식화에 사용해요.
Args의 각 Ti에 대해 std::formatter<std::remove_cvref_t<Ti>, CharT>가 BasicFormatter 요구 사항을 충족하지 않으면 동작이 정의되지 않아요.
매개변수
fmt
형식 문자열을 나타내는 객체예요. 형식 문자열은 일반 문자({와 } 제외)로 구성되며, 이 문자들은 출력에 그대로 복사돼요. 이스케이프 시퀀스 {{와 }}는 각각 {와 }로 대체돼요. 그리고 치환 필드(replacement fields)가 있어요.
각 치환 필드는 다음과 같은 형식을 가져요.
{ arg-id(선택) }(1) — 형식 지정이 없는 치환 필드{ arg-id(선택) : format-spec }(2) — 형식 지정이 있는 치환 필드
arg-id는 args에서 형식화에 사용할 인자의 인덱스를 지정해요. 생략하면 인자가 순서대로 사용돼요. 형식 문자열의 arg-id들은 모두 있거나 모두 생략해야 해요. 수동 인덱싱과 자동 인덱싱을 섞으면 오류예요.
format-spec는 해당 인자에 대한 std::formatter 특수화로 정의된 형식 지정이에요. }로 시작할 수 없어요.
- 기본 타입과 표준 문자열 타입의 경우 형식 지정은 표준 형식 지정(standard format specification)으로 해석돼요.
- chrono 타입의 경우 형식 지정은 chrono 형식 지정으로 해석돼요.
- 범위(range) 타입의 경우 형식 지정은 범위 형식 지정으로 해석돼요.
std::pair와std::tuple의 경우 형식 지정은 튜플 형식 지정으로 해석돼요.std::thread::id와std::stacktrace_entry의 경우 스레드 ID 형식 지정 및 스택트레이스 항목 형식 지정을 참고하세요.std::basic_stacktrace의 경우 형식 지정자를 허용하지 않아요. (since C++23)std::filesystem::path의 경우 경로 형식 지정을 참고하세요. (since C++26)- 다른 형식화 가능한 타입의 경우 형식 지정은 사용자 정의 formatter 특수화에 의해 결정돼요.
args...
형식화할 인자들이에요.
loc
로케일별 형식화에 사용할 std::locale이에요.
반환 값
형식화된 문자열의 총 문자 수를 반환해요.
예외
포맷터가 던지는 모든 예외를 전파해요.
예제
#include <format>
#include <iomanip>
#include <iostream>
#include <string_view>
#include <vector>
int main()
{
using namespace std::literals::string_view_literals;
constexpr auto fmt_str{"Hubble's H{0} {1} {2:*^4} miles/sec/mpc."sv};
constexpr auto sub_zero{"\N{SUBSCRIPT ZERO}"sv}; // "₀" or {0342, 130, 128}
constexpr auto aprox_equ{"\N{APPROXIMATELY EQUAL TO}"sv}; // "≅" or {0342, 137, 133}
constexpr int Ho{42}; // H₀
const auto min_buffer_size{std::formatted_size(fmt_str, sub_zero, aprox_equ, Ho)};
std::cout << "Min buffer size = " << min_buffer_size << '\n';
// Use std::vector as dynamic buffer. The buffer does not include the trailing '\0'.
std::vector<char> buffer(min_buffer_size);
std::format_to_n(buffer.data(), buffer.size(), fmt_str, sub_zero, aprox_equ, Ho);
std::cout << "Buffer: "
<< std::quoted(std::string_view{buffer.data(), min_buffer_size})
<< '\n';
// Print the buffer directly after adding the trailing '\0'.
buffer.push_back('\0');
std::cout << "Buffer: " << std::quoted(buffer.data()) << '\n';
}
출력:
Min buffer size = 37
Buffer: "Hubble's H₀ ≅ *42* miles/sec/mpc."
Buffer: "Hubble's H₀ ≅ *42* miles/sec/mpc."
결함 보고서
다음의 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용되었어요.
| DR | 적용 대상 | 발표된 동작 | 올바른 동작 |
|---|---|---|---|
| P2216R3 | C++20 | 잘못된 형식 문자열에 대해 std::format_error를 던짐 |
잘못된 형식 문자열은 컴파일 타임 오류를 발생시킴 |
| P2418R2 | C++20 | const로 사용할 수 없거나 복사할 수 없는 객체(예: generator류 객체)는 형식화할 수 없음 | 이러한 객체의 형식화를 허용 |
| P2508R1 | C++20 | 이 기능에 사용자에게 보이는 이름이 없음 | basic_format_string 이름이 노출됨 |
같이 보기
format_to (C++20) |
출력 반복자를 통해 인자의 형식화된 표현을 써넣어요 (함수 템플릿) |
|---|---|
format_to_n (C++20) |
지정된 크기를 초과하지 않으면서 출력 반복자를 통해 인자의 형식화된 표현을 써넣어요 (함수 템플릿) |