namespace std {
template <class charT>
using fmt-iter-for = unspecified;
template <class T, class Context, class Formatter = typename Context::template formatter_type<remove_const_t<T>>>>
concept formattable-with = // 説明専用
semiregular<Formatter> &&
requires(Formatter& f,
const Formatter& cf,
T&& t,
Context fc,
basic_format_parse_context<typename Context::char_type> pc) {
{ f.parse(pc) } -> same_as<typename decltype(pc)::iterator>;
{ cf.format(t, fc) } -> same_as<typename Context::iterator>;
};
template <class T, class charT>
concept formattable =
formattable-with<remove_reference_t<T>, basic_format_context<fmt-iter-for<charT>>>;
}
概要
formattableは、文字列フォーマット可能であることを表すコンセプトである。
このコンセプトを使用することで、formatterクラステンプレートが使用したい型で特殊化されているかをチェックできる。
formattableコンセプトの定義において使用されているfmt-iter-for<charT>は、output_iterator<const charT&>コンセプトのモデルとなる未規定の型である。
例
#include <iostream>
#include <format>
#include <any>
template <std::formattable<char> T>
void f(T x) {
std::cout << std::format("{}", x) << std::endl;
}
int main() {
f(3); // OK
f("hello"); // OK
//f(std::any{3}); // NG : std::anyはstd::formatterを特殊化していない
}
出力
3
hello
バージョン
言語
- C++23
処理系
- Clang: ??
- GCC: 13 ✅
- Visual C++: ??