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_const_t
<
Ti
>>
не удовлетворяет требованиям
BasicFormatter
для любого
Ti
в
Args
.
Программа является некорректной, если для любого типа
Ti
в
Args
,
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 > ( 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)
(C++20)
(C++20)
|
класс, предоставляющий доступ ко всем аргументам форматирования
(шаблон класса) |
|
(C++20)
|
нетемплейтный вариант
std::format
с использованием type-erased представления аргументов
(функция) |
|
(C++20)
|
нетемплейтный вариант
std::format_to
с использованием type-erased представления аргументов
(шаблон функции) |