std::make_format_args, std::make_wformat_args
Определено в заголовочном файле <format> | ||
template<class Context =std::format_context, class... Args> /*format-arg-store*/<Context, Args...> | (1) | (начиная с C++20) |
template<class... Args> /*format-arg-store*/<std::wformat_context, Args...> | (2) | (начиная с C++20) |
Возвращает объект, который хранит массив аргументов форматирования и может быть неявно преобразован в std::basic_format_args<Context>.
Поведение не определено, если typename Context::template formatter_type<std::remove_cvref_t<Ti>> не соответствует требованиям BasicFormatter для любого Ti
в Args
.
Программа некорректна, если для любого типа Ti
в Args
, std::remove_reference_t<Ti> не соответствует __formattable_with<Context>.
Содержание |
[править]Параметры
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>(t); - иначе, если
TD
является целочисленным типом со знаком, размер которого не превышает int, то std::basic_format_arg хранит static_cast<int>(t); - иначе, если
TD
представляет собой целочисленный тип без знака, размер которого не превышает unsignedint, то std::basic_format_arg хранит static_cast<unsignedint>(t); - иначе, если
TD
является целочисленным типом со знаком, размер которого не превышает longlong, то std::basic_format_arg хранит static_cast<longlong>(t); - иначе, если
TD
представляет собой целочисленный тип без знака, размер которого не превышает unsignedlonglong, то std::basic_format_arg хранит static_cast<unsignedlonglong>(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<constvoid*>(t);
- иначе std::basic_format_arg хранит std::basic_format_arg<Context>::handle в
t
вместе с дополнительными данными, необходимыми дляhandle::format()
.
[править]Примечание
Аргумент форматирования имеет ссылочную семантику для пользовательских типов и не продлевает время жизни args. Программист несёт ответственность за то, чтобы args пережил возвращаемое значение. Обычно результат используется только как аргумент функции форматирования.
[править]Пример
#include <array>#include <format>#include <iostream>#include <string_view> void raw_write_to_log(std::string_view users_fmt, std::format_args&& args){staticint n{};std::clog<<std::format("{:04} : ", n++)<<std::vformat(users_fmt, args)<<'\n';} template<typename... Args>constexprvoid log(Args&&... args){// Создаёт строку форматирования "{} "...std::array<char, sizeof...(Args)*3+1> braces{};constexprconstchar 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...));} int main(){ log("Количество", "аргументов", "произвольно."); log("Любой тип, соответствующий требованиям BasicFormatter,", "можно распечатать."); log("Например:", 1, 2.0, '3', "*42*"); raw_write_to_log("{:02} │ {} │ {} │ {}", std::make_format_args(1, 2.0, '3', "4"));}
Вывод:
0000 : Количество аргументов произвольно. 0001 : Любой тип, соответствующий требованиям BasicFormatter, можно распечатать. 0002 : Например: 1 2.0 3 *42* 0003 : 01 │ 2.0 │ 3 │ 4
[править]Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
Номер | Применён | Поведение в стандарте | Корректное поведение |
---|---|---|---|
WG не указан | C++20 | объекты, которые не являются ни константными, ни копируемыми (например, объекты, подобные генераторам), не форматируются | форматирование этих объектов разрешено |
LWG 3631 | c++20 | cv-квалифицированные аргументы неправильно обрабатывались после P2418R2 | обработка исправлена |
[править]Смотрите также
(C++20)(C++20)(C++20) | класс, который обеспечивает доступ ко всем аргументам форматирования (шаблон класса) |
(C++20) | нешаблонный вариант std::format с использованием представления аргументов с удалением типа (функция) |
(C++20) | нешаблонный вариант std::format_to с использованием представления аргументов с удалением типа (шаблон функции) |