format_formatter

format_formatter (서식 지정자 클래스 템플릿)

std::formatter는 주어진 타입에 대한 서식 지정 규칙을 정의하는 클래스 템플릿이에요. C++20에서 도입되었으며, std::format과 같은 형식화 기능에서 타입별 출력 형식을 제어하는 핵심 역할을 해요. 이 페이지에서는 기본 특수화와 표준 형식 지정, 라이브러리 타입에 대한 특수화 등을 다룬답니다.

출처: cppreference

본문

개요

std::formatter의 활성화된 특수화는 주어진 타입에 대한 서식 지정 규칙을 정의해요. 활성화된 특수화는 BasicFormatter 요구 사항을 충족하며, 별도로 명시되지 않는 한 Formatter 요구 사항도 충족해요.

특수화 std::formatter<T, CharT>가 활성화되지 않은 모든 타입 TCharT에 대해, 그 특수화는 완전한 타입이며 비활성화되어 있어요.

비활성화된 특수화는 Formatter 요구 사항을 충족하지 않으며, 다음 모두가 false예요:

  • std::is_default_constructible_v
  • std::is_copy_constructible_v
  • std::is_move_constructible_v
  • std::is_copy_assignable_v
  • std::is_move_assignable_v

기본 표준 특수화

다음 목록에서 CharTchar 또는 wchar_t이고, ArithmeticTchar, wchar_t, char8_t, char16_t, char32_t를 제외한 cv 한정되지 않은 산술 타입이에요.

문자 포맷터

특수화 번호
template <> struct formatter<char, char>; (1)
template <> struct formatter<char, wchar_t>; (2)
template <> struct formatter<wchar_t, wchar_t>; (3)

문자열 포맷터

특수화 번호
template <> struct formatter<CharT*, CharT>; (4)
template <> struct formatter<const CharT*, CharT>; (5)
template <std::size_t N> struct formatter<CharT[N], CharT>; (6)
template <class Traits, class Alloc> struct formatter<std::basic_string<CharT, Traits, Alloc>, CharT>; (7)
template <class Traits> struct formatter<std::basic_string_view<CharT, Traits>, CharT>; (8)

산술 포맷터

특수화 번호
template <> struct formatter<ArithmeticT, CharT>; (9)

포인터 포맷터

특수화 번호
template <> struct formatter<std::nullptr_t, CharT>; (10)
template <> struct formatter<void*, CharT>; (11)
template <> struct formatter<const void*, CharT>; (12)

다른 포인터와 멤버 포인터에 대한 포맷터는 비활성화되어 있어요.

인코딩 변환이 필요한 std::formatter<wchar_t, char>std::formatter<const char*, wchar_t> 같은 특수화는 비활성화되어 있어요.

wchar_t에 대한 비활성화된 포맷터 (C++23)

C++23에서는 일부 char 시퀀스가 wchar_t 범위로 서식 지정되는 것을 방지하기 위해 다음 특수화가 여전히 비활성화되어 있어요.

특수화 번호
template <> struct formatter<char*, wchar_t>; (1)
template <> struct formatter<const char*, wchar_t>; (2)
template <std::size_t N> struct formatter<char[N], wchar_t>; (3)
template <class Traits, class Allocator> struct formatter<std::basic_string<char, Traits, Allocator>, wchar_t>; (4)
template <class Traits> struct formatter<std::basic_string_view<char, Traits>, wchar_t>; (5)

디버그 활성화 포맷터 특수화는 추가로 공용 비정적 멤버 함수 constexpr void set_debug_format();을 제공해요. 이 함수는 마지막 parse 호출에서 파싱된 형식 지정자의 타입이 ?였던 것처럼 값이 이스케이프되고 인용되어 서식 지정되도록 포맷터 객체의 상태를 수정해요. 문자열 또는 문자 타입에 대한 각 포맷터 특수화는 디버그 활성화되어 있어요.

표준 형식 지정

이 섹션은 불완전해요. 이유: 표준 형식 지정은 별도 페이지로 이동되었어요. 섹션 제목은 이 섹션으로의 링크를 위해 임시로 유지되고 있어요. 모든 링크가 정리된 후 이 섹션은 제거될 예정이에요.

라이브러리 타입에 대한 표준 특수화

특수화 설명
std::formatter<std::chrono::duration> (C++20) duration에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::sys_time> (C++20) sys_time에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::utc_time> (C++20) utc_time에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::tai_time> (C++20) tai_time에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::gps_time> (C++20) gps_time에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::file_time> (C++20) file_time에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::local_time> (C++20) local_time에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::day> (C++20) day에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::month> (C++20) month에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::year> (C++20) year에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::weekday> (C++20) weekday에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::weekday_indexed> (C++20) weekday_indexed에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::weekday_last> (C++20) weekday_last에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::month_day> (C++20) month_day에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::month_day_last> (C++20) month_day_last에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::month_weekday> (C++20) month_weekday에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::month_weekday_last> (C++20) month_weekday_last에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::year_month> (C++20) year_month에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::year_month_day> (C++20) year_month_day에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::year_month_day_last> (C++20) year_month_day_last에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::year_month_weekday> (C++20) year_month_weekday에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::year_month_weekday_last> (C++20) year_month_weekday_last에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::hh_mm_ss> (C++20) hh_mm_ss에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::sys_info> (C++20) sys_info에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::local_info> (C++20) local_info에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::chrono::zoned_time> (C++20) zoned_time에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::basic_stacktrace> (C++23) basic_stacktrace에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::stacktrace_entry> (C++23) stacktrace_entry에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::thread::id> (C++23) thread::id에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::vector<bool>::reference> (C++23) vector<bool>::reference에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<pair-or-tuple> (C++23) pairtuple에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<range> (C++23) 범위에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::stack> (C++23) std::stack에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::queue> (C++23) std::queue에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::priority_queue> (C++23) std::priority_queue에 대한 서식 지정 지원 (클래스 템플릿 특수화)
std::formatter<std::filesystem::path> (C++26) filesystem::path에 대한 서식 지정 지원 (클래스 템플릿 특수화)

예제

#include <algorithm>
#include <format>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string_view>
 
struct QuotableString : std::string_view
{};
 
template<>
struct std::formatter<QuotableString, char>
{
    bool quoted = false;

    template<class ParseContext>
    constexpr ParseContext::iterator parse(ParseContext& ctx)
    {
        auto it = ctx.begin();
        if (it == ctx.end())
            return it;
            
        if (*it == '#')
        {
            quoted = true;
            ++it;
        }
        if (it != ctx.end() && *it != '}')
            throw std::format_error("Invalid format args for QuotableString.");
            
        return it;
    }
 
    template<class FmtContext>
    FmtContext::iterator format(QuotableString s, FmtContext& ctx) const
    {
        std::ostringstream out;
        if (quoted)
            out << std::quoted(s);
        else
            out << s;

        return std::ranges::copy(std::move(out).str(), ctx.out()).out;
    }
};
 
int main()
{
    QuotableString a("be"), a2(R"( " be " )");
    QuotableString b("a question");
    std::cout << std::format("To {0} or not to {0}, that is {1}.\n", a, b);
    std::cout << std::format("To {0:} or not to {0:}, that is {1:}.\n", a, b);
    std::cout << std::format("To {0:#} or not to {0:#}, that is {1:#}.\n", a2, b);
}

출력:

To be or not to be, that is a question.
To be or not to be, that is a question.
To " \" be \" " or not to " \" be \" ", that is "a question".

결함 보고서

다음 동작 변경 결함 보고서는 이전에 발표된 C++ 표준에 소급 적용되었어요.

DR 적용 대상 발표된 동작 올바른 동작
LWG 3944 C++23 일부 char 시퀀스가 wchar_t 범위로 서식 지정 가능했음 비활성화 특수화 추가

같이 보기

이름 설명
basic_format_context, format_context, wformat_context (C++20) 모든 서식 인자와 출력 반복자를 포함한 서식 지정 상태 (클래스 템플릿)
formattable (C++23) 타입이 서식 지정 가능함을 지정, 즉 std::formatter를 특수화하고 parseformat 멤버 함수를 제공함 (컨셉)
range_formatter (C++23) 범위 타입에 대한 std::formatter 특수화 구현을 돕는 클래스 템플릿 (클래스 템플릿)

더 알아보기 (Learn more)

cppreference