Namespaces
Variants

std:: make_format_args, std:: make_wformat_args

From cppreference.net
Определено в заголовке <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 является беззнаковым целочисленным типом, размер которого не превышает unsigned int , то std::basic_format_arg сохраняет static_cast < unsigned int > ( t ) ;
  • в противном случае, если TD является знаковым целочисленным типом, размер которого не превышает long long , то std::basic_format_arg сохраняет static_cast < long long > ( t ) ;
  • в противном случае, если TD является беззнаковым целочисленным типом, размер которого не превышает unsigned long long , то std::basic_format_arg сохраняет static_cast < unsigned long long > ( t ) ;
  • в противном случае, если TD является float , double , или long double , то 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)
(DR)
Форматирование кодовых единиц как беззнаковых целых чисел

Пример

#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++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
P2418R2 C++20 объекты, которые не являются ни const-usable, ни копируемыми
(такие как generator-like объекты) не форматируемы
разрешить форматирование этих объектов
P2905R2 C++20 make_format_args принимал rvalue аргументы через forwarding references принимает только lvalue ссылки
P2909R4 C++20 char или wchar_t могли форматироваться как
беззнаковые целочисленные значения вне диапазона
кодовые единицы преобразуются в соответствующий
беззнаковый тип перед таким форматированием
LWG 3631 C++20 cv-квалифицированные аргументы некорректно обрабатывались после P2418R2 обработка исправлена

Смотрите также

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