namespace std {
template<class Context = format_context, class... Args>
format_arg_store<Context, Args...> make_format_args(const Args&... args); // (1)
template<class... Args>
format_arg_store<wformat_context, Args...> make_wformat_args(const Args&... args); // (2)
}
概要
可変長引数の型を消去して、basic_format_arg
の列に変換する。
戻り値の型 format_arg_store
は便宜上次の通り定義されるが、その型名は規格に含まれない。
namespace std {
template<class Context, class... Args>
struct format_arg_store { // exposition only
array<basic_format_arg<Context>, sizeof...(Args)> args;
};
}
basic_format_args
はformat_arg_store
から構築できる。
make_format_args
の結果はただちにbasic_format_args
へ変換するのが意図された使い方である。
template<class... Args>
string format(string_view fmt, const Args&... args)
{
return vformat(fmt, {make_format_args(args...)}); // format_arg_store から format_args へ暗黙変換
}
事前条件
すべての引数の型Ti
についてContext::formatter_type<Ti>
がFormatter
要件を満たすこと。
効果
(2)は次と等しい。
return make_format_args<wformat_context>(args...);
(1)は次と等しい。
return {basic_format_arg<Context>(args)...}
ただし、便宜上、basic_format_arg
は次のprivateメンバを持つとする。
(これらのprivateメンバは規格に含まれない)
namespace std {
template<class Context>
class basic_format_arg {
public:
class handle;
private:
using charT = typename Context::char_type;
variant<monostate, bool, charT,
int, unsigned int, long long int, unsigned long long int,
float, double, long double,
const charT*, basic_string_view<charT>,
const void*, handle> value;
template<typename T> explicit basic_format_arg(const T& v) noexcept; // (a)
explicit basic_format_arg(float n) noexcept; // (b)
explicit basic_format_arg(double n) noexcept; // (c)
explicit basic_format_arg(long double n) noexcept; // (d)
explicit basic_format_arg(const charT* s); // (e)
template<class traits>
explicit basic_format_arg(
basic_string_view<charT, traits> s) noexcept; // (f)
template<class traits, class Allocator>
explicit basic_format_arg(
const basic_string<charT, traits, Allocator>& s) noexcept; // (g)
explicit basic_format_arg(nullptr_t) noexcept; // (h)
template<class T>
explicit basic_format_arg(const T* p) noexcept; // (i)
template<class Ctx, class... Args>
friend format_arg_store<Ctx, Args...>
make_format_args(const Args&... args);
};
}
ここで、それぞれの効果は次と等しい。
- (a):
T
がbool
またはcharT
なら、value
をv
で初期化- または、
T
がchar
かつcharT
がwchar_t
なら、value
をstatic_cast<wchar_t>(v)
で初期化 - または、
T
が符号つき整数型かつsizeof(T) <= sizeof(int)
なら、value
をstatic_cast<int>(v)
で初期化 - または、
T
が符号なし整数型かつsizeof(T) <= sizeof(unsigned int)
なら、value
をstatic_cast<unsigned int>(v)
で初期化 - または、
T
が符号つき整数型かつsizeof(T) <= sizeof(long long int)
なら、value
をstatic_cast<long long int>(v)
で初期化 - または、
T
が符号なし整数型かつsizeof(T) <= sizeof(unsigned long long int)
なら、value
をstatic_cast<unsigned long long int>(v)
で初期化 - または、
value
をhandle(v)
で初期化
- (b),(c),(d):
value
をn
で初期化 - (e):
value
をs
で初期化 (s
は有効なC文字列であること) - (f):
value
をs
で初期化 - (g):
value
をbasic_string_view<charT>(s.data(), s.size())
で初期化 - (h):
value
をstatic_cast<const void*>(nullptr)
で初期化 - (i):
value
をp
で初期化 (is_void_v<T>
がtrue
であること)
戻り値
{basic_format_arg<Context>(args)...}
実装例
namespace std {
template<class Context = format_context, class... Args>
format_arg_store<Context, Args...> make_format_args(const Args&... args)
{
return {basic_format_arg<Context>(args)...}
}
template<class... Args>
format_arg_store<wformat_context, Args...> make_wformat_args(const Args&... args)
{
return make_format_args<wformat_context>(args...);
}
}
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??