std::make_format_args, std::make_wformat_args
來自 cppreference.com
定義於標頭檔案 <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>> 不滿足 Args
中任何 Ti
的 BasicFormatter 要求,則行為未定義。
如果 Args
中任何型別 Ti
不滿足 __formattable_with<Context>,則程式格式錯誤。
2) 等價於 return std::make_format_args<std::wformat_context>(args...);。
目錄 |
[edit] 引數
args... | - | 用作格式化引數的值 |
[edit] 返回
一個包含格式化引數的物件。
對於型別為 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 儲存一個指向
t
的 std::basic_format_arg<Context>::handle,以及handle::format()
所需的額外資料。
[edit] 註記
格式化引數對使用者定義型別具有引用語義,並且不會延長 args 的生命週期。程式設計師有責任確保 args 的生命週期長於返回值。通常,結果僅用作格式化函式的引數。
特性測試宏 | 值 | 標準 | 特性 |
---|---|---|---|
__cpp_lib_format_uchar |
202311L |
(C++20) (DR) |
將程式碼單元格式化為無符號整數 |
[edit] 示例
執行此程式碼
#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
[edit] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
P2418R2 | C++20 | 既不可 const 使用也不可複製的物件 (例如生成器類物件) 不可格式化 |
允許格式化這些物件 |
P2905R2 | C++20 | make_format_args 透過轉發引用接受右值引數 |
只接受左值引用 |
P2909R4 | C++20 | char 或 wchar_t 可能會被格式化為 超出範圍的無符號整數值 |
程式碼單元在進行此類格式化之前轉換為相應的 無符號型別 |
LWG 3631 | C++20 | P2418R2 後,cv 限定引數處理不正確 | 處理已更正 |
[edit] 參閱
(C++20)(C++20)(C++20) |
提供對所有格式化引數訪問的類 (類模板) |
(C++20) |
使用型別擦除引數表示的 std::format 的非模板變體 (函式) |
(C++20) |
使用型別擦除引數表示的 std::format_to 的非模板變體 (函式模板) |