Spec-Zone.ru › C++

std::make_format_args, std::make_wformat_args

Определено в заголовочном файле <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>.

Поведение не определено, если typename Context::template formatter_type<std::remove_const_t<Ti>> не удовлетворяет требованиям BasicFormatter для любого Ti в Args.

Программа некорректна, если для любого типа Ti в Args, Ti не удовлетворяет требованиям __formattable_with<Context>.

2) Эквивалентно return std::make_format_args<std::wformat_context>(args...);.

Параметры

args... - значения, используемые в качестве аргументов форматирования

Возвращаемое значение

Объект, содержащий аргументы форматирования.

Для каждого аргумента t типа T пусть TD будет std::remove_const_t<std::remove_reference_t<T>>. Соответствующий std::basic_format_arg в результате определяется следующим образом:

  • если TD является bool или Context::char_type, std::basic_format_arg хранит t;
  • иначе, если TD является char, а Context::char_type — wchar_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 является беззнаковым целочисленным типом, размер которого не превышает размер unsignedint, std::basic_format_arg хранит static_cast<unsigned int>(t);
  • иначе, если TD является знаковым целочисленным типом, размер которого не превышает размер longlong, std::basic_format_arg хранит static_cast<long long>(t);
  • иначе, если TD является беззнаковым целочисленным типом, размер которого не превышает размер unsignedlonglong, std::basic_format_arg хранит static_cast<unsigned long long>(t);
  • иначе, если TD является float, double или longdouble, std::basic_format_arg хранит t;
  • иначе, если TD является специализацией std::basic_string_view или std::basic_string и TD::char_type является Context::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>> является true или std::is_null_pointer_v<TD> является true, std::basic_format_arg хранит static_cast<const void*>(t);
  • иначе std::basic_format_arg хранит std::basic_format_arg<Context>::handle для t вместе с дополнительными данными, необходимыми для handle::format().

Примечания

Для типов, определённых пользователем, аргумент форматирования имеет семантику ссылки и не продлевает время жизни args. Программист должен обеспечить, чтобы args существовали дольше возвращаемого значения. Обычно результат используется только в качестве аргумента функции форматирования.

Макрос проверки поддержки функциональности Значение Стандарт Функциональность
__cpp_lib_format_uchar 202311L (C++20)
(отчёт об ошибке)
Форматирование кодовых единиц как беззнаковых целых чисел

Пример

#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)
{
    // Generate formatting string "{} "...
    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 объекты, которые нельзя ни использовать как константные, ни копировать
(например, объекты, похожие на генераторы), не являются форматируемыми
разрешено форматирование таких объектов
P2905R2 C++20 make_format_args принимала аргументы-правые значения посредством forwarding references принимает только ссылки на lvalue
P2909R4 C++20 char или wchar_t могли форматироваться как
беззнаковые целые значения вне допустимого диапазона
перед таким форматированием кодовые единицы преобразуются в соответствующий
беззнаковый тип
LWG 3631 C++20 аргументы с квалификаторами cv некорректно обрабатывались после P2418R2 обработка исправлена

См. также

basic_format_argsformat_argswformat_args
(C++20)(C++20)(C++20)
класс, предоставляющий доступ ко всем аргументам форматирования
(шаблон класса)
vformat
(C++20)
нетемплейтный вариант std::format с использованием представления аргументов с устранением типов
(функция)
vformat_to
(C++20)
нетемплейтный вариант std::format_to с использованием представления аргументов с устранением типов
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/format/make_format_args

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API