std::make_format_args, std::make_wformat_args
| Definiert in Header <format> |
||
| template< class Context = std::format_context, class... Args > /*format-arg-store*/<Context, Args...> |
(1) | (seit C++20) |
| template< class... Args > /*format-arg-store*/<std::wformat_context, Args...> |
(2) | (seit C++20) |
Gibt ein Objekt zurück, das ein Array von Formatierungsargumenten speichert und implizit in std::basic_format_args<Context> konvertiert werden kann.
Das Verhalten ist undefiniert, wenn typename Context::template formatter_type<std::remove_const_t<Ti>> nicht die BasicFormatter-Anforderungen für ein beliebiges Ti in Args erfüllt.
Das Programm ist fehlerhaft, wenn für einen beliebigen Typ Ti in Args gilt, dass Ti nicht __formattable_with<Context> erfüllt.
Inhalt |
[edit] Parameter
| args... | - | Werte, die als Formatierungsargumente verwendet werden sollen |
[edit] Rückgabewert
Ein Objekt, das die Formatierungsargumente enthält.
Für jedes Argument t vom Typ T sei TD std::remove_const_t<std::remove_reference_t<T>>. Das entsprechende std::basic_format_arg im Ergebnis wird wie folgt bestimmt:
- wenn
TDbool oderContext::char_typeist, speichert das std::basic_format_arg t; - andernfalls, wenn
TDchar ist undContext::char_typewchar_t ist, speichert das std::basic_format_arg static_cast<wchar_t>(static_cast<unsigned char>(t)); - andernfalls, wenn
TDein vorzeichenbehafteter Ganzzahltyp ist, dessen Größe nicht größer als int ist, speichert das std::basic_format_arg static_cast<int>(t); - andernfalls, wenn
TDein vorzeichenloser Ganzzahltyp ist, dessen Größe nicht größer als unsigned int ist, speichert das std::basic_format_arg static_cast<unsigned int>(t); - andernfalls, wenn
TDein vorzeichenbehafteter Ganzzahltyp ist, dessen Größe nicht größer als long long ist, speichert das std::basic_format_arg static_cast<long long>(t); - andernfalls, wenn
TDein vorzeichenloser Ganzzahltyp ist, dessen Größe nicht größer als unsigned long long ist, speichert das std::basic_format_arg static_cast<unsigned long long>(t); - andernfalls, wenn
TDfloat, double oder long double ist, speichert das std::basic_format_arg t; - andernfalls, wenn
TDeine Spezialisierung von std::basic_string_view oder std::basic_string ist undTD::char_typeContext::char_typeist, speichert das std::basic_format_arg std::basic_string_view<Context::char_type>(t.data(), t.size()); - andernfalls, wenn std::decay_t<TD> Context::char_type* oder const Context::char_type* ist, speichert das std::basic_format_arg static_cast<const Context::char_type*>(t);
- andernfalls, wenn std::is_void_v<std::remove_pointer_t<TD>> true ist oder std::is_null_pointer_v<TD> true ist, speichert das std::basic_format_arg static_cast<const void*>(t);
- andernfalls speichert das std::basic_format_arg einen std::basic_format_arg<Context>::handle für
tzusammen mit zusätzlichen Daten, die fürhandle::format()benötigt werden.
[edit] Anmerkungen
Ein Formatierungsargument hat Referenzsemantik für benutzerdefinierte Typen und verlängert nicht die Lebensdauer von args. Es liegt in der Verantwortung des Programmierers sicherzustellen, dass args länger lebt als der Rückgabewert. Üblicherweise wird das Ergebnis nur als Argument für eine Formatierungsfunktion verwendet.
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_format_uchar |
202311L |
(C++20) (DR) |
Formatierung von Code-Einheiten als vorzeichenlose Ganzzahlen |
[edit] Beispiel
#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")); }
Ausgabe
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
[edit] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| P2418R2 | C++20 | Objekte, die weder const-benutzbar noch kopierbar sind. (wie Generator-ähnliche Objekte) sind nicht formatierbar |
Ermöglichen der Formatierung dieser Objekte |
| P2905R2 | C++20 | make_format_args akzeptierte rvalue-Argumente über Weiterleitungsreferenzen |
nur lvalue-Referenzen werden übernommen |
| P2909R4 | C++20 | char oder wchar_t können formatiert werden als außerhalb des gültigen Bereichs liegende vorzeichenlose Ganzzahlwerte |
Code-Einheiten werden in den entsprechenden vorzeichenlosen Typ konvertiert, bevor diese Formatierung erfolgt |
| LWG 3631 | C++20 | cv-qualifizierte Argumente wurden nach P2418R2 falsch behandelt | Behandlung korrigiert |
[edit] Siehe auch
| (C++20)(C++20)(C++20) |
Klasse, die Zugriff auf alle Formatierungsargumente ermöglicht (Klassentemplate) |
| (C++20) |
nicht-Template-Variante von std::format mit typ-erased Argumentdarstellung (Funktion) |
| (C++20) |
nicht-Template-Variante von std::format_to mit typ-erased Argumentdarstellung (Funktionstemplate) |