format_range_formatter

format_range_formatter (범위 포맷터)

이 페이지는 C++23에서 추가된 std::range_formatter 클래스 템플릿에 대해 설명해요. 범위(range)의 std::formatter 특수화를 구현할 때 사용하는 헬퍼 클래스예요. 이 포맷터를 통해 범위의 요소를 어떻게 출력할지, 대괄호나 구분자 등을 어떻게 지정할지 정할 수 있어요.

출처: cppreference

본문

std::range_formatter<format> 헤더에 정의되어 있으며, 범위 타입에 대한 std::formatter 특수화를 직접 구현하지 않고도 일관된 형식 지정 문법을 제공해요.

Defined in header <format>
template < class T , class CharT = char > requires std :: same_as < std :: remove_cvref_t < T > , T > && std :: formattable < T , CharT > class range_formatter ; (since C++23)

Range format specification

range-format-spec의 문법은 다음과 같아요.

range-fill-and-align (선택) width (선택) n (선택) range-type (선택) range-underlying-spec (선택)

range-fill-and-align은 일반적인 fill-and-align과 같은 방식으로 해석되지만, 채움 문자는 {, }, : 외의 문자만 사용할 수 있어요.

width는 표준 format width specification에서 설명하는 방식과 동일해요.

n 옵션을 사용하면 범위를 여는 대괄호와 닫는 대괄호 없이 출력해요.

assert(std::format("{}", views::iota(1, 5)) == "[1, 2, 3, 4]");
assert(std::format("{:n}", views::iota(1, 5)) == "1, 2, 3, 4");

range-underlying-spec 안의 format-spec은 문법적으로 : format-spec과 동일하며, 범위 요소의 포맷터인 std::formatter<T, CharT>가 해석해요.

std::array ints{12, 10, 15, 14};

assert(std::format("{}", ints) == "[12, 10, 15, 14]");
assert(std::format("{::X}", ints) == "[C, A, F, E]");
assert(std::format("{:n:_^4}", ints) == "_12_, _10_, _15_, _14_");

range-type은 범위가 출력되는 방식을 바꾸며, 일부 옵션은 특정 인자 타입에서만 유효해요.

사용 가능한 range presentation type은 다음과 같아요.

  • m: 여는 대괄호를 {, 닫는 대괄호를 }, 구분자를 , 로 사용하고, 각 범위 요소를 마치 tuple-format-spec에서 m을 지정한 것처럼 포맷해요.
  • range-type으로 m을 선택한 경우, Tstd::pair의 특수화이거나 std::tuple_size_v<T> == 2를 만족하는 std::tuple의 특수화가 아니라면 프로그램은 ill-formed예요.
std::array char_pairs
{
    std::pair{'A', 5}, std::pair{'B', 10}, std::pair{'C', 12}
};

assert(std::format("{}", char_pairs) == "[('A', 5), ('B', 10), ('C', 12)]");
assert(std::format("{:m}", char_pairs) == "{'A': 5, 'B': 10, 'C': 12}");
  • s: 범위를 문자열로 포맷해요.
  • ?s: 범위를 이스케이프된 문자열(escaped string)로 포맷해요.
  • s 또는 ?srange-type으로 선택한 경우, n 옵션과 range-underlying-spec은 형식 지정자에 포함되면 안 되고, TCharT가 아니라면 프로그램은 ill-formed예요.
std::array star{'S', 'T', 'A', 'R'};

assert(std::format("{}", star) == "['S', 'T', 'A', 'R']");
assert(std::format("{:s}", star) == "STAR");
assert(std::format("{:?s}", star) == "\"STAR\"");

Data members

Member name Definition
std :: formatter < T , CharT > underlying_ (private) 요소를 포맷하는 내부 포맷터예요. exposition-only member object예요.
std :: basic_string_view < CharT > separator_ (private) 범위 포맷 결과의 구분자를 나타내는 문자열이에요. 기본 구분자는 ", "예요. exposition-only member object예요.
std :: basic_string_view < CharT > opening-bracket_ (private) 범위 포맷 결과의 여는 대괄호를 나타내는 문자열이에요. 기본 여는 대괄호는 "["예요. exposition-only member object예요.
std :: basic_string_view < CharT > closing-bracket_ (private) 범위 포맷 결과의 닫는 대괄호를 나타내는 문자열이에요. 기본 닫는 대괄호는 "]"예요. exposition-only member object예요.

Member functions

Member function Description
set_separator 범위 포맷 결과에 사용할 구분자를 지정해요. (public member function)
set_brackets 범위 포맷 결과에 사용할 여는 대괄호와 닫는 대괄호를 지정해요. (public member function)
underlying 내부 포맷터를 반환해요. (public member function)
parse range-format-spec에 따라 형식 지정자를 파싱해요. (public member function)
format range-format-spec에 따라 범위 포맷 결과를 출력해요. (public member function)

std::range_formatter:: set_separator

constexpr void set_separator ( std :: basic_string_view < CharT > sep ) noexcept ;

sepseparator_에 지정해요.

std::range_formatter:: set_brackets

constexpr void set_brackets ( std :: basic_string_view < CharT > opening , std :: basic_string_view < CharT > closing ) noexcept ;

openingclosing을 각각 opening-bracket_closing-bracket_에 지정해요.

std::range_formatter:: underlying

constexpr std :: formatter < T , CharT >& underlying ();
constexpr const std :: formatter < T , CharT >& underlying () const ;

underlying_(내부 포맷터)를 반환해요.

std::range_formatter:: parse

template < class ParseContext >
constexpr auto parse ( ParseContext & ctx ) -> ParseContext :: iterator ;

형식 지정자를 range-format-spec으로 파싱하고, 파싱된 지정자를 현재 객체에 저장해요.

range-format-spec 안의 format-spec을 파싱하기 위해 underlying_.parse(ctx)를 호출해요. format-spec이 없다면 빈 format-spec으로 간주해요.

range-type이나 n 옵션이 있으면 opening-bracket_, closing-bracket_, separator_의 값을 필요에 따라 수정해요.

다음 조건을 모두 만족하면 underlying_.set_debug_format()을 호출해요.

  • range-types?s도 아닌 경우
  • underlying_.set_debug_format()이 유효한 표현식인 경우
  • range-underlying-spec이 없는 경우

range-format-spec의 끝을 가리키는 반복자를 반환해요.

std::range_formatter:: format

template < ranges :: input_range R , class FormatContext > requires std :: formattable < ranges :: range_reference_t < R > , CharT > && std :: same_as < std :: remove_cvref_t < ranges :: range_reference_t < R >> , T > auto format ( R && r , FormatContext & ctx ) const -> FormatContext :: iterator ;

range-types 또는 ?s였다면, std::basic_string<CharT>(std::from_range, r)을 각각 문자열 또는 이스케이프된 문자열로 포맷하여 ctx.out()에 출력해요.

그렇지 않으면 range-format-spec에 따라 다음을 순서대로 ctx.out()에 출력해요.

  • opening-bracket_
  • 범위 r의 각 포맷 가능한 요소 e에 대해:
    • underlying_를 통해 e를 출력한 결과
    • er의 마지막 요소가 아니라면 separator_
  • closing-bracket_

출력 범위의 끝을 가리키는 반복자를 반환해요.

Defect reports

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

DR Applied to Behavior as published Correct behavior
LWG 3892 C++23 중첩 범위의 포맷이 올바르지 않았음 수정됨

See also

formatter (C++20) 주어진 타입에 대한 형식 지정 규칙을 정의해요. (class template)

더 알아보기 (Learn more)

cppreference