はじめに(Introduction)
N4910 Working Draft, Standard for Programming Language C++
n4910は、ISO/IEC JTC1 SC22 WG21の作業原案(Working Draft)です。
公式のISO/IEC 14882原本ではありません。
ISO/IEC JTC1 SC22 WG21では、可能な限り作業文書を公開し、幅広い意見を求めています。
一連の記事はコード断片をコンパイルできる形にする方法を検討してコンパイル、リンク、実行して、規格案の原文と処理系(g++, Clang++)との違いを確認し、技術内容を検討し、ISO/IEC JTC1 SC22 WG21にフィードバックするために用います。
また、CERT C++, MISRA C++等のコーディング標準のコード断片をコンパイルする際の参考にさせていただこうと考えています。CERT C++, MISRA C++が標準化の動きとの時間的なずれがあれば確認できれば幸いです。また、boostライブラリとの関連、Linux OS, TOPPERSカーネル、g++(GCC), clang++(LLVM)との関係も調査中です。
何か、抜け漏れ、耳より情報がありましたらおしらせくださると幸いです。
<この項は書きかけです。順次追記します。>
背景(back ground)
C/C++でコンパイルエラーが出ると、途方にくれることがしばしばあります。
何回かに1回は、該当するエラーが検索できます。
ただ、条件が違っていて、そこでの修正方法では目的を達成しないこともしばしばです。いろいろな条件のコンパイルエラーとその対応方法について、広く記録することによって、いつか同じエラーに遭遇した時にやくに立つことを目指しています。
この半年の間で、三度、自分のネットでの記録に助けられたことがあります。
また過去に解決できなかった記録を10種類以上、最近になって解決できたことがあります。それは、主に次の3つの情報に基づいています。
cpprefjp - C++日本語リファレンス
コンパイラの実装状況
また
https://researchmap.jp/joub9b3my-1797580/#_1797580
に記載したサイトのお世話になっています。
作業方針(sequence)
Clang++では-std=c++03, C++2bの2種類
g++では-std=c++03, c++2bの2種類
でコンパイルし、
1)コンパイルエラーを収集する。
2)コンパイルエラーをなくす方法を検討する。
コンパイルエラーになる例を示すだけが目的のコードは、コンパイルエラーをなくすのではなく、コンパイルエラーの種類を収集するだけにする。
文法を示すのが目的のコード場合に、コンパイルエラーをなくすのに手間がかかる場合は、順次作業します。
3)リンクエラーをなくす方法を検討する。
文法を示すのが目的のコード場合に、リンクエラーをなくすのに手間がかかる場合は、順次作業します。
4)意味のある出力を作る。
コンパイル、リンクが通っても、意味のある出力を示そうとすると、コンパイル・リンクエラーが出て収拾できそうにない場合がある。順次作業します。
1)だけのものから4)まで進んだものと色々ある状態です。一歩でも前に進むご助言をお待ちしています。「検討事項」の欄に現状を記録するようにしています。
C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
C++N4741, 2018 Standard Working Draft on ISO/IEC 14882 sample code compile list
C++N4606, 2016符号断片編纂一覧(example code compile list)
C++N4606, 2016 Working Draft 2016, ISO/IEC 14882, C++ standard(1) Example code compile list
https://qiita.com/kaizen_nagoya/items/df5d62c35bd6ed1c3d43/
C++N3242, 2011 sample code compile list on clang++ and g++
編纂器(Compiler)
clang++ --version
Debian clang version 14.0.5-++20220610033153+c12386ae247c-1~exp1~20220610153237.151
Target: x86_64-pc-linux-gnu, Thread model: posix, InstalledDir: /usr/bin
g++- --version
g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22.14 Formatting [format] C++N4910:2022 (632) p770.cpp
算譜(source code)
// C++N4910 Committee Draft, Standard for Programming Language C++
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4910.pdf
const char * n4910 = "22.14 Formatting [format] C++N4910:2022 (632) p770.cpp";
// Debian clang version 14.0.5-++20220610033153+c12386ae247c-
// g++ (GCC) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc.
// Edited by Dr. OGAWA Kiyoshi. Compile procedure and results record.
// C++N4910:2022 Standard Working Draft on ISO/IEC 14882(0) sample code compile list
// https://qiita.com/kaizen_nagoya/items/fc957ddddd402004bb91
#include "N4910.h"
using namespace std;
// Example 1
22.14.1 Header <format> synopsis
namespace std {
// 22.14.6.4, class template basic_format_context
template<class Out, class charT> class basic_format_context;
using format_context = basic_format_context<unspecified, char>; using wformat_context = basic_format_context<unspecified, wchar_t>;
// 22.14.7.3, class template basic_format_args
template<class Context> class basic_format_args;
using format_args = basic_format_args<format_context>; using wformat_args = basic_format_args<wformat_context>;
[format] [format.syn]
§ 22.14.1
770
© ISO/IEC
N4910
// 22.14.4, class template basic-format-string template<class charT, class... Args>
struct basic-format-string ;
template<class... Args> using format-string =
// exposition only
// exposition only
basic-format-string<char, type_identity_t<Args>...>; template<class... Args>
using wformat-string = // exposition only basic-format-string<wchar_t, type_identity_t<Args>...>;
// 22.14.5, formatting functions template<class... Args>
string format(format-string<Args...> fmt, Args&&... args); template<class... Args>
wstring format(wformat-string<Args...> fmt, Args&&... args); template<class... Args>
string format(const locale& loc, format-string<Args...> fmt, Args&&... args); template<class... Args>
wstring format(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
string vformat(string_view fmt, format_args args);
wstring vformat(wstring_view fmt, wformat_args args);
string vformat(const locale& loc, string_view fmt, format_args args);
wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
template<class Out, class... Args>
Out format_to(Out out, format-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, Args&&... args);
template<class Out>
Out vformat_to(Out out, string_view fmt, format_args args);
template<class Out>
Out vformat_to(Out out, wstring_view fmt, wformat_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, wstring_view fmt, wformat_args args);
template<class Out> struct format_to_n_result {
Out out;
iter_difference_t<Out> size;
};
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
format-string<Args...> fmt, Args&&... args); format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
wformat-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, wformat-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
template<class... Args>
size_t formatted_size(format-string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(wformat-string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
// 22.14.6, formatter
template<class T, class charT = char> struct formatter;
// 22.14.6.3, class template basic_format_parse_context
template<class charT> class basic_format_parse_context;
using format_parse_context = basic_format_parse_context<char>; using wformat_parse_context = basic_format_parse_context<wchar_t>;
// 22.14.7, arguments
// 22.14.7.1, class template basic_format_arg template<class Context> class basic_format_arg;
template<class Visitor, class Context>
decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
// 22.14.7.2, class template format-arg-store
template<class Context, class... Args> class format-arg-store;
template<class Context = format_context, class... Args> format-arg-store<Context, Args...>
make_format_args(Args&&... fmt_args);
template<class... Args>
format-arg-store<wformat_context, Args...> make_wformat_args(Args&&... args);
// 22.14.8, class format_error
class format_error;
}
// exposition only
// The class template format_to_n_result has the template parameters, data members, and special members specified above. It has no base classes or members other than those specified.
// 22.14.2 Format string [format.string]
// 22.14.2.1 In general [format.string.general]
// A format string for arguments args is a (possibly empty) sequence of replacement fields, escape sequences, and characters other than { and }. Let charT be the character type of the format string. Each character that is not part of a replacement field or an escape sequence is copied unchanged to the output. An escape sequence is one of {{ or }}. It is replaced with { or }, respectively, in the output. The syntax of replacement fields is as follows:
replacement-field :
{ arg-idopt format-specifieropt }
arg-id : 0
positive-integer
positive-integer : nonzero-digit
positive-integer digit
nonnegative-integer : digit
nonnegative-integer digit
nonzero-digit: one of 123456789
// digit: one of 0123456789
format-specifier :
: format-spec
format-spec :
as specified by the formatter specialization for the argument type
// The arg-id field specifies the index of the argument in args whose value is to be formatted and inserted into the output instead of the replacement field. If there is no argument with the index arg-id in args, the string is not a format string for args. The optional format-specifier field explicitly specifies a format for the replacement value.
// [Example 1 :
string s = format("{0}-{{", 8); // value of s is "8-{"
// 4 If all arg-ids in a format string are omitted (including those in the format-spec, as interpreted by the corresponding formatter specialization), argument indices 0, 1, 2, . . . will automatically be used in that order. If some arg-ids are omitted and some are present, the string is not a format string.
// [Note 1: A format string cannot contain a mixture of automatic and manual indexing.
// [Example 2:
string s0 = format("{} to {}", "a", "b");
string s1 = format("{1} to {0}", "a", "b");
string s2 = format("{0} to {}", "a", "b");
string s3 = format("{} to {1}", "a", "b");
// OK, automatic indexing
// OK, manual indexing
// not a format string (mixing automatic and manual indexing), // ill-formed
// not a format string (mixing automatic and manual indexing), // ill-formed
// The format-spec field contains format specifications that define how the value should be presented. Each type can define its own interpretation of the format-spec field. If format-spec does not conform to the format specifications for the argument type referred to by arg-id, the string is not a format string for args.
// [Example 3:
// — For arithmetic, pointer, and string types the format-spec is interpreted as a std-format-spec as described
// Each formatter specializations described in 22.14.6.2 for fundamental and string types interprets format-spec as a std-format-spec.
// [Note 1: The format specification can be used to specify such details as field width, alignment, padding, and decimal precision. Some of the formatting options are only supported for arithmetic types. —end note]
// The syntax of format specifications is as follows:
std-format-spec :
fill-and-alignopt signopt #opt 0opt widthopt precisionopt Lopt typeopt
fill-and-align : fillopt align
fill :
any character other than { or }
align: one of <>^
sign: one of
+ - space
// in (22.14.2.2).
// — For chrono types the format-spec is interpreted as a chrono-format-spec as described in (29.12).
// — For user-defined formatter specializations, the behavior of the parse member function determines how the format-spec is interpreted.
// 22.14.2.2 Standard format specifiers [format.string.std]
width : positive-integer
{ arg-idopt }
precision :
. nonnegative-integer
. { arg-idopt } type: one of
aAbBcdeEfFgGopsxX
// [Note 2: The fill character can be any character other than { or }. The presence of a fill character is signaled by the character following it, which must be one of the alignment options. If the second character of std-format-spec is not a valid alignment option, then it is assumed that both the fill character and the alignment option are absent. — end note ]
// The align specifier applies to all argument types. The meaning of the various alignment options is as specified in Table 64.
// [Example 1:
char c = 120;
string s0 = format("{:6}", 42);
string s1 = format("{:6}", 'x');
string s2 = format("{:*<6}", 'x');
string s3 = format("{:*>6}", 'x');
string s4 = format("{:*^6}", 'x');
string s5 = format("{:6d}", c);
string s6 = format("{:6}", true);
// value of s0 is " 42" //valueof s1is"x " // value of s2 is "x*****" // value of s3 is "*****x" // value of s4 is "**x***" // value of s5 is " 120" // value of s6 is "true "
// [Note 3: Unless a minimum field width is defined, the field width is determined by the size of the content and the
alignment option has no effect. —end note]
// Table 64: Meaning of align options [tab:format.align]
Option Meaning
< Forces the field to be aligned to the start of the available space. // This is the default for non-arithmetic non-pointer types, charT, and bool, unless an integer presentation type is specified.
> Forces the field to be aligned to the end of the available space.
// This is the default for arithmetic types other than charT and bool, pointer types, or when an integer presentation type is specified.
^ Forces the field to be centered within the available space by inserting n characters 2
before and n characters after the value, where n is the total number of fill characters 2
to insert.
// The sign option is only valid for arithmetic types other than charT and bool or when an integer presentation type is specified. The meaning of the various options is as specified in Table 65.
Table 65: Meaning of sign options [tab:format.sign]
Option Meaning
+ Indicates that a sign should be used for both non-negative and negative numbers. The + sign is inserted before the output of to_chars for non-negative numbers other than
negative zero.
// [Note 4: For negative numbers and negative zero the output of to_chars will already contain the sign so no additional transformation is performed.
- Indicates that a sign should be used for negative numbers and negative zero only (this is the default behavior).
space Indicates that a leading space should be used for non-negative numbers other than negative zero, and a minus sign for negative numbers and negative zero.
5 The sign option applies to floating-point infinity and NaN. § 22.14.2.2
— u+1100 – u+115f — u+2329 – u+232a — u+2e80 – u+303e — u+3040 – u+a4cf — u+ac00 – u+d7a3 — u+f900 – u+faff — u+fe10 – u+fe19 — u+fe30 – u+fe6f — u+ff00 – u+ff60 — u+ffe0 – u+ffe6 — u+1f300 – u+1f64f — u+1f900 – u+1f9ff — u+20000 – u+2fffd — u+30000 – u+3fffd
// [Example 2:
double inf = numeric_limits<double>::infinity();
double nan = numeric_limits<double>::quiet_NaN();
string s0 = format("{0:},{0:+},{0:-},{0: }", 1);
string s1 = format("{0:},{0:+},{0:-},{0: }", -1);
string s2 = format("{0:},{0:+},{0:-},{0: }", inf);
string s3 = format("{0:},{0:+},{0:-},{0: }", nan);
// value of s0 is "1,+1,1, 1"
// value of s1 is "-1,-1,-1,-1"
// value of s2 is "inf,+inf,inf, inf" // value of s3 is "nan,+nan,nan, nan"
6 The # option causes the alternate form to be used for the conversion. This option is valid for arithmetic types other than charT and bool or when an integer presentation type is specified, and not otherwise. For integral types, the alternate form inserts the base prefix (if any) specified in Table 67 into the output after the sign character (possibly space) if there is one, or before the output of to_chars otherwise. For floating-point types, the alternate form causes the result of the conversion of finite values to always contain a decimal-point character, even if no digits follow it. Normally, a decimal-point character appears in the result of these conversions only if a digit follows it. In addition, for g and G conversions, trailing zeros are not removed from the result.
// If { arg-idopt } is used in a width or precision, the value of the corresponding formatting argument is used in its place. If the corresponding formatting argument is not of integral type, or its value is negative for precision or non-positive for width, an exception of type format_error is thrown.
// The positive-integer in width is a decimal integer defining the minimum field width. If width is not specified, there is no minimum field width, and the field width is determined based on the content of the field.
// The width of a string is defined as the estimated number of column positions appropriate for displaying it in a terminal.
// [Note 5: This is similar to the semantics of the POSIX wcswidth function.
// For the purposes of width computation, a string is assumed to be in a locale-independent, implementation- defined encoding. Implementations should use a Unicode encoding on platforms capable of displaying Unicode text in a terminal.
[Note 6: This is the case for Windows210-based and many POSIX-based operating systems. —end note]
11 For a string in a Unicode encoding, implementations should estimate the width of a string as the sum of estimated widths of the first code points in its extended grapheme clusters. The extended grapheme clusters of a string are defined by UAX #29. The estimated width of the following code points is 2:
The estimated width of other code points is 1.
12 For a string in a non-Unicode encoding, the width of a string is unspecified.
210) Windows® is a registered trademark of Microsoft Corporation. This information is given for the convenience of users of this document and does not constitute an endorsement by ISO or IEC of this product.
// — For integral types, the locale-specific form causes the context’s locale to be used to insert the appropriate digit group separator characters.
// — For floating-point types, the locale-specific form causes the context’s locale to be used to insert the appropriate digit group and radix separator characters.
// — For the textual representation of bool, the locale-specific form causes the context’s locale to be used to insert the appropriate string as if obtained with numpunct::truename or numpunct::falsename.
// A zero (0) character preceding the width field pads the field with leading zeros (following any indication of sign or base) to the field width, except when applied to an infinity or NaN. This option is only valid for arithmetic types other than charT and bool or when an integer presentation type is specified. If the 0 character and an align option both appear, the 0 character is ignored.
// [Example 3:
char c = 120;
string s1 = format("{:+06d}", c);
string s2 = format("{:#06x}", 0xa);
string s3 = format("{:<06}", -42);
// value of s1 is "+00120"
// value of s2 is "0x000a"
// value of s3 is "-42 " (0 is ignored because of < alignment)
// The nonnegative-integer in precision is a decimal integer defining the precision or maximum field size. It can only be used with floating-point and string types. For floating-point types this field specifies the formatting precision. For string types, this field provides an upper bound for the estimated width of the prefix of the input string that is copied into the output. For a string in a Unicode encoding, the formatter copies to the output the longest prefix of whole extended grapheme clusters whose estimated width is no greater than the precision.
// When the L option is used, the form used for the conversion is called the locale-specific form. The L option is only valid for arithmetic types, and its effect depends upon the type.
// The type determines how the data should be presented.
// The available string presentation types are specified in Table 66.
Table 66: Meaning of type options for strings [tab:format.type.string]
// The meaning of some non-string presentation types is defined in terms of a call to to_chars. In such cases, let [first, last) be a range large enough to hold the to_chars output and value be the formatting argument value. Formatting is done as if by calling to_chars as specified and copying the output through the output iterator of the format context.
// [Note 7: Additional padding and adjustments are performed prior to copying the output through the output iterator as specified by the format specifiers.
// The available integer presentation types for integral types other than bool and charT are specified in Table 67. [Example 4:
Type Meaning
none, s Copies the string to the output.
string s0 = format("{}", 42);
string s1 = format("{0:b} {0:d} {0:o} {0:x}", 42);
string s2 = format("{0:#x} {0:#X}", 42);
string s3 = format("{:L}", 1234);
// value of s0 is "42"
// value of s1 is "101010 42 52 2a" // value of s2 is "0x2a 0X2A"
// value of s3 can be "1,234"
// (depending on the locale)
// The available charT presentation types are specified in Table 68.
// The available bool presentation types are specified in Table 69.
// The available floating-point presentation types and their meanings for values other than infinity and NaN are specified in Table 70. For lower-case presentation types, infinity and NaN are formatted as inf and nan, respectively. For upper-case presentation types, infinity and NaN are formatted as INF and NAN, respectively.
// [Note 9: In either case, a sign is included if indicated by the sign option.
// Table 67: Meaning of type options for integer types [tab:format.type.int]
Type Meaning
b to_chars(first, last, value, 2); the base prefix is 0b.
B The same as b, except that the base prefix is 0B.
c Copies the character static_cast<charT>(value) to the output. Throws format_- error if value is not in the range of representable values for charT.
d to_chars(first, last, value).
o to_chars(first, last, value, 8); the base prefix is 0 if value is nonzero and is empty otherwise.
x to_chars(first, last, value, 16); the base prefix is 0x.
X The same as x, except that it uses uppercase letters for digits above // and the base prefix is 0X.
none The same as d.
// [Note 8: If the formatting argument type is charT or bool, the default is instead c or s, respectively.
// Table 68: Meaning of type options for charT [tab:format.type.char]
// Table 69: Meaning of type options for bool [tab:format.type.bool]
// Table 70: Meaning of type options for floating-point types [tab:format.type.float]
Type Meaning
none, c Copies the character to the output.
b, B, d, o, x, X As specified in Table 67.
Type Meaning
none, s Copies textual representation, either true or false, to the output.
b, B, d, o, x, X As specified in Table 67 for the value static_cast<unsigned char>(value).
Type Meaning
a If precision is specified, equivalent to
to_chars(first, last, value, chars_format::hex, precision)
where precision is the specified formatting precision; equivalent to to_chars(first, last, value, chars_format::hex)
otherwise.
A The same as a, except that it uses uppercase letters for digits above 9 and P to indicate the exponent.
e Equivalent to
to_chars(first, last, value, chars_format::scientific, precision)
where precision is the specified formatting precision, or 6 if precision is not specified.
E The same as e, except that it uses E to indicate exponent.
f, F Equivalent to
to_chars(first, last, value, chars_format::fixed, precision)
where precision is the specified formatting precision, or 6 if precision is not specified.
g Equivalent to
to_chars(first, last, value, chars_format::general, precision)
where precision is the specified formatting precision, or 6 if precision is not specified.
G The same as g, except that it uses E to indicate exponent.
none If precision is specified, equivalent to
to_chars(first, last, value, chars_format::general, precision)
where precision is the specified formatting precision; equivalent to to_chars(first, last, value)
otherwise.
// Effects: Equivalent to:
return vformat(fmt.str, make_format_args(args...));
// The available pointer presentation types and their mapping to to_chars are specified in Table 71. [Note 10: Pointer presentation types also apply to nullptr_t. —end note]
// Table 71: Meaning of type options for pointer types [tab:format.type.ptr]
// 22.14.3 Error reporting [format.err.report]
// Formatting functions throw format_error if an argument fmt is passed that is not a format string for args. They propagate exceptions thrown by operations of formatter specializations and iterators. Failure to allocate storage is reported by throwing an exception as described in 16.4.6.13.
Type Meaning
none, p If uintptr_t is defined,
to_chars(first, last, reinterpret_cast<uintptr_t>(value), 16)
with the prefix 0x added to the output; otherwise, implementation-defined.
// 22.14.4 Class template basic-format-string [format.fmt.string]
template<class charT, class... Args>
struct basic-format-string { // exposition only private:
basic_string_view<charT> str ; // exposition only
public:
template<class T> consteval basic-format-string(const T& s);
};
template<class T> consteval basic-format-string(const T& s);
// Constraints: const T& models convertible_to<basic_string_view<charT>>.
// Effects: Direct-non-list-initializes str with s.
// Remarks: A call to this function is not a core constant expression (7.7) unless there exist args of types Args such that str is a format string for args.
// In the description of the functions, operator + is used for some of the iterator categories for which it does not have to be defined. In these cases the semantics of a + n are the same as in 27.2.
template<class... Args>
string format(format-string<Args...> fmt, Args&&... args);
// 22.14.5 Formatting functions [format.functions]
template<class... Args>
wstring format(wformat-string<Args...> fmt, Args&&... args);
Effects: Equivalent to:
return vformat(fmt.str, make_wformat_args(args...));
template<class... Args>
string format(const locale& loc, format-string<Args...> fmt, Args&&... args);
// Effects: Equivalent to:
return vformat(loc, fmt.str, make_format_args(args...));
template<class... Args>
wstring format(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
// Effects: Equivalent to:
return vformat(loc, fmt.str, make_wformat_args(args...));
Returns: A string object holding the character representation of formatting arguments provided by args formatted according to specifications given in fmt. If present, loc is used for locale-specific formatting.
string vformat(string_view fmt, format_args args);
wstring vformat(wstring_view fmt, wformat_args args);
string vformat(const locale& loc, string_view fmt, format_args args);
wstring vformat(const locale& loc, wstring_view fmt, wformat_args args);
Throws: As specified in 22.14.3. template<class Out, class... Args>
Out format_to(Out out, format-string<Args...> fmt, Args&&... args);
// Effects: Equivalent to:
return vformat_to(std::move(out), fmt.str, make_format_args(args...)); template<class Out, class... Args>
Out format_to(Out out, wformat-string<Args...> fmt, Args&&... args);
// Effects: Equivalent to:
return vformat_to(std::move(out), fmt.str, make_wformat_args(args...)); template<class Out, class... Args>
Out format_to(Out out, const locale& loc, format-string<Args...> fmt, Args&&... args); Effects: Equivalent to:
return vformat_to(std::move(out), loc, fmt.str, make_format_args(args...)); template<class Out, class... Args>
Out format_to(Out out, const locale& loc, wformat-string<Args...> fmt, Args&&... args); Effects: Equivalent to:
return vformat_to(std::move(out), loc, fmt.str, make_wformat_args(args...));
template<class Out>
Out vformat_to(Out out, string_view fmt, format_args args);
template<class Out>
Out vformat_to(Out out, wstring_view fmt, wformat_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, string_view fmt, format_args args);
template<class Out>
Out vformat_to(Out out, const locale& loc, wstring_view fmt, wformat_args args);
Let charT be decltype(fmt)::value_type.
// Constraints: Out satisfies output_iterator<const charT&>. Preconditions: Out models output_iterator<const charT&>.
// Effects: Places the character representation of formatting the arguments provided by args, formatted according to the specifications given in fmt, into the range [out, out + N), where N is the number of characters in that character representation. If present, loc is used for locale-specific formatting.
// Returns: out + N.
// Throws: As specified in 22.14.3.
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
format-string<Args...> fmt, Args&&... args); format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
wformat-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class Out, class... Args>
// — it meets the
// — Cpp17DefaultConstructible (Table 29), — Cpp17CopyConstructible (Table 31), — Cpp17CopyAssignable (Table 33), and — Cpp17Destructible (Table 34)
(3.1) (3.2)
// — fisavalueoftypeF, — u is an lvalue of type T,
template<class Out, class... Args>
format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n,
const locale& loc, wformat-string<Args...> fmt, Args&&... args);
// A type F meets the BasicFormatter requirements if:
// Let — charT be decltype(fmt.str )::value_type,
// — N be formatted_size(fmt, args...) for the functions without a loc parameter and formatted_- size(loc, fmt, args...) for the functions with a loc parameter, and
// — M be clamp(n, 0, N).
// Constraints: Out satisfies output_iterator<const charT&>.
// Preconditions: Out models output_iterator<const charT&>, and formatter<remove_cvref_t<Ti>, charT> meets the BasicFormatter requirements (22.14.6.1) for each Ti in Args.
// Effects: Places the first M characters of the character representation of formatting the arguments provided by args, formatted according to the specifications given in fmt, into the range [out, out + M). If present, loc is used for locale-specific formatting.
Returns: {out + M, N}. Throws: As specified in 22.14.3.
template<class... Args>
size_t formatted_size(format-string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(wformat-string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, format-string<Args...> fmt, Args&&... args);
template<class... Args>
size_t formatted_size(const locale& loc, wformat-string<Args...> fmt, Args&&... args);
// Let charT be decltype(fmt.str )::value_type.
// Preconditions: formatter<remove_cvref_t<Ti>, charT> meets the BasicFormatter requirements
(22.14.6.1) for each Ti in Args.
// Returns: The number of characters in the character representation of formatting arguments args
formatted according to specifications given in fmt. If present, loc is used for locale-specific formatting. Throws: As specified in 22.14.3.
// 22.14.6 Formatter [format.formatter]
// 22.14.6.1 Formatter requirements [formatter.requirements]
requirements,
— it is swappable (16.4.4.3) for lvalues, and
— the expressions shown in Table 72 are valid and have the indicated semantics.
// A type F meets the Formatter requirements if it meets the BasicFormatter requirements and the expressions shown in Table 73 are valid and have the indicated semantics.
3 Given character type charT, output iterator type Out, and formatting argument type T, in Table 72 and Table 73:
// — t is a value of a type convertible to (possibly const) T, — PC is basic_format_parse_context<charT>,
// — FC is basic_format_context<Out, charT>,
// — pc is an lvalue of type PC, and
// — fc is an lvalue of type FC.
// — The specializations
template<> struct formatter<char, char>;
template<> struct formatter<char, wchar_t>;
template<> struct formatter<wchar_t, wchar_t>;
// — For each charT, the string type specializations template<> struct formatter<charT*, charT>;
pc.begin() points to the beginning of the format-spec (22.14.2) of the replacement field being formatted in the format string. If format-spec is empty then either pc.begin() == pc.end() or *pc.begin() == ’}’.
// Table 72: BasicFormatter requirements
[tab:formatter.basic] [tab:formatter]
Expression Return type Requirement
f.parse(pc)
PC::iterator
Parses format-spec (22.14.2) for type T in the range [pc.begin(), pc.end()) until the first un- matched character. Throws format_error un- less the whole range is parsed or the unmatched character is }.
[Note 1: This allows formatters to emit meaningful error messages. —end note]
Stores the parsed format specifiers in *this and returns an iterator past the end of the parsed range.
f.format(u, fc)
FC::iterator
Formats u according to the specifiers stored in *this, writes the output to fc.out(), and re- turns an iterator past the end of the output range. The output shall only depend on u, fc.locale(), fc.arg(n) for any value n of type size_t, and the range [pc.begin(), pc.end()) from the last
call to f.parse(pc).
Table 73: Formatter requirements
Expression Return type Requirement
f.format(t, fc)
FC::iterator
Formats t according to the specifiers stored in *this, writes the output to fc.out(), and re- turns an iterator past the end of the output range. The output shall only depend on t, fc.locale(), fc.arg(n) for any value n of type size_t, and the range [pc.begin(), pc.end()) from the last
call to f.parse(pc).
f.format(u, fc) FC::iterator As above, but does not modify u.
22.14.6.2 Formatter specializations
[format.formatter.spec]
1 The functions defined in 22.14.5 use specializations of the class template formatter to format individual arguments.
2 Let charT be either char or wchar_t. Each specialization of formatter is either enabled or disabled, as described below. Each header that declares the template formatter provides the following enabled specializations:
— is_default_constructible_v<F>, — is_copy_constructible_v<F>,
— is_move_constructible_v<F>,
— is_copy_assignable_v<F>, and — is_move_assignable_v<F>.
template<> struct formatter<const charT*, charT>;
template<size_t N> struct formatter<const charT[N], charT>;
template<class traits, class Allocator>
struct formatter<basic_string<charT, traits, Allocator>, charT>;
template<class traits>
struct formatter<basic_string_view<charT, traits>, charT>;
— For each charT, for each cv-unqualified arithmetic type ArithmeticT other than char, wchar_t, char8_t, char16_t, or char32_t, a specialization
template<> struct formatter<ArithmeticT, charT>;
— For each charT, the pointer type specializations
template<> struct formatter<nullptr_t, charT>;
template<> struct formatter<void*, charT>;
template<> struct formatter<const void*, charT>;
3 For any types T and charT for which neither the library nor the user provides an explicit or partial specialization of the class template formatter, formatter<T, charT> is disabled.
4 If the library provides an explicit or partial specialization of formatter<T, charT>, that specialization is enabled and meets the Formatter requirements except as noted otherwise.
5 If F is a disabled specialization of formatter, these values are false:
The parse member functions of these formatters interpret the format specification as a std-format-spec as described in 22.14.2.2.
[Note 1: Specializations such as formatter<wchar_t, char> and formatter<const char*, wchar_t> that would require implicit multibyte / wide string or character conversion are disabled. —end note]
6 An enabled specialization formatter<T, charT> meets the BasicFormatter requirements (22.14.6.1). [Example 1:
#include <format>
enum color { red, green, blue };
const char* color_names[] = { "red", "green", "blue" };
template<> struct std::formatter<color> : std::formatter<const char*> {
auto format(color c, format_context& ctx) {
return formatter<const char*>::format(color_names[c], ctx);
}
};
struct err {};
std::string s0
std::string s1
std::string s2
std::string s3
= std::format("{}", 42);
= std::format("{}", L"foo");
= std::format("{}", red);
= std::format("{}", err{});
// OK, library-provided formatter // error: disabled formatter
// OK, user-provided formatter // error: disabled formatter
22.14.6.3 Class template basic_format_parse_context [format.parse.ctx]
namespace std {
template<class charT>
class basic_format_parse_context {
public:
using char_type = charT;
using const_iterator = typename basic_string_view<charT>::const_iterator;
Effects: Initializes begin_ with fmt.begin(), end_ with fmt.end(), indexing_ with unknown, next_- arg_id_ with 0, and num_args_ with num_args.
using iterator = const_iterator;
private:
iterator begin_;
iterator end_;
enum indexing { unknown, manual, automatic };
indexing indexing_;
size_t next_arg_id_;
size_t num_args_;
// exposition only // exposition only // exposition only // exposition only // exposition only // exposition only
public:
constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
size_t num_args = 0) noexcept;
basic_format_parse_context(const basic_format_parse_context&) = delete;
basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr void advance_to(const_iterator it);
constexpr size_t next_arg_id();
constexpr void check_arg_id(size_t id);
};
}
1 An instance of basic_format_parse_context holds the format string parsing state consisting of the format string range being parsed and the argument counter for automatic indexing.
constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
size_t num_args = 0) noexcept;
constexpr const_iterator begin() const noexcept;
Returns: begin_.
constexpr const_iterator end() const noexcept;
Returns: end_.
constexpr void advance_to(const_iterator it);
Preconditions: end() is reachable from it. Effects: Equivalent to: begin_ = it;
constexpr size_t next_arg_id();
Effects: If indexing_ != manual, equivalent to:
if (indexing_ == unknown)
indexing_ = automatic;
return next_arg_id_++;
Throws: format_error if indexing_ == manual which indicates mixing of automatic and manual argument indexing.
constexpr void check_arg_id(size_t id);
Effects: If indexing_ != automatic, equivalent to: if (indexing_ == unknown)
indexing_ = manual;
Throws: format_error if indexing_ == automatic which indicates mixing of automatic and manual argument indexing.
Remarks: Call expressions where id >= num_args_ are not core constant expressions (7.7).
Returns: The locale passed to the formatting function if the latter takes one, and std::locale() otherwise.
© ISO/IEC
N4910
22.14.6.4 Class template basic_format_context
namespace std {
template<class Out, class charT>
class basic_format_context {
basic_format_args<basic_format_context> args_;
Out out_;
[format.context]
public:
using iterator = Out;
using char_type = charT;
template<class T> using formatter_type = formatter<T, charT>;
basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
std::locale locale();
iterator out();
void advance_to(iterator it);
};
}
1 An instance of basic_format_context holds formatting state consisting of the formatting arguments and the output iterator.
2 Out shall model output_iterator<const charT&>.
3 format_context is an alias for a specialization of basic_format_context with an output iterator that appends to string, such as back_insert_iterator<string>. Similarly, wformat_context is an alias for a specialization of basic_format_context with an output iterator that appends to wstring.
4 Recommended practice: For a given type charT, implementations should provide a single instantiation of basic_format_context for appending to basic_string<charT>, vector<charT>, or any other container with contiguous storage by wrapping those in temporary objects with a uniform interface (such as a span<charT>) and polymorphic reallocation.
basic_format_arg<basic_format_context> arg(size_t id) const noexcept;
Returns: args_.get(id). std::locale locale();
iterator out();
Effects: Equivalent to: return std::move(out_);
void advance_to(iterator it);
Effects: Equivalent to: out_ = std::move(it); [Example 1:
struct S { int value; };
template<> struct std::formatter<S> {
size_t width_arg_id = 0;
// Parses a width argument id in the format { digit }. constexpr auto parse(format_parse_context& ctx) {
auto iter = ctx.begin();
auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; };
if (get_char() != '{')
return iter;
++iter;
char c = get_char();
if (!isdigit(c) || (++iter, get_char()) != '}')
throw format_error("invalid format");
width_arg_id = c - '0';
// exposition only // exposition only
ctx.check_arg_id(width_arg_id);
return ++iter;
}
// Formats an S with width given by the argument width_arg_id. auto format(S s, format_context& ctx) {
int width = visit_format_arg([](auto value) -> int {
if constexpr (!is_integral_v<decltype(value)>)
throw format_error("width is not integral");
else if (value < 0 || value > numeric_limits<int>::max())
throw format_error("invalid width");
else
return value;
}, ctx.arg(width_arg_id));
return format_to(ctx.out(), "{0:x<{1}}", s.value, width);
} };
std::string s = std::format("{0:{1}}", S{42}, 10);
22.14.7 Arguments [format.arg]
22.14.7.1 Class template basic_format_arg [format.arguments]
namespace std {
template<class Context>
class basic_format_arg {
public:
class handle;
private:
using char_type = typename Context::char_type;
variant<monostate, bool, char_type,
int, unsigned int, long long int, unsigned long long int,
float, double, long double,
const char_type*, basic_string_view<char_type>,
const void*, handle> value;
template<class T> explicit basic_format_arg(T&& v) noexcept;
explicit basic_format_arg(float n) noexcept;
explicit basic_format_arg(double n) noexcept;
explicit basic_format_arg(long double n) noexcept;
explicit basic_format_arg(const char_type* s);
template<class traits>
explicit basic_format_arg(
basic_string_view<char_type, traits> s) noexcept;
template<class traits, class Allocator>
explicit basic_format_arg(
const basic_string<char_type, traits, Allocator>& s) noexcept;
explicit basic_format_arg(nullptr_t) noexcept;
template<class T>
explicit basic_format_arg(T* p) noexcept;
public:
basic_format_arg() noexcept;
explicit operator bool() const noexcept;
};
}
// value of s is "xxxxxxxx42"
// exposition only
// exposition only
// exposition only // exposition only // exposition only // exposition only // exposition only
// exposition only
// exposition only // exposition only
// exposition only
// Postconditions: !(*this).
// An instance of basic_format_arg provides access to a formatting argument for user-defined formatters.
// The behavior of a program that adds specializations of basic_format_arg is undefined.
basic_format_arg() noexcept;
template<class T> explicit basic_format_arg(T&& v) noexcept;
// Constraints: The template specialization
typename Context::template formatter_type<remove_cvref_t<T>>
meets the BasicFormatter requirements (22.14.6.1). The extent to which an implementation determines that the specialization meets the BasicFormatter requirements is unspecified, except that as a minimum the expression
typename Context::template formatter_type<remove_cvref_t<T>>()
.format(declval<T&>(), declval<Context&>())
// shall be well-formed when treated as an unevaluated operand (7.2.3).
// Effects:— if T is bool or char_type, initializes value with v;
// — otherwise, if T is char and char_type is wchar_t, initializes value with static_cast<wchar_-
t>(v);
// — otherwise, if T is a signed integer type (6.8.2) and sizeof(T) <= sizeof(int), initializes value
with static_cast<int>(v);
// — otherwise, if T is an unsigned integer type and sizeof(T) <= sizeof(unsigned int), initializes
value with static_cast<unsigned int>(v);
// — otherwise, if T is a signed integer type and sizeof(T) <= sizeof(long long int), initializes
value with static_cast<long long int>(v);
// — otherwise, if T is an unsigned integer type and sizeof(T) <= sizeof(unsigned long long
int), initializes value with static_cast<unsigned long long int>(v);
// — otherwise, initializes value with handle(v).
explicit basic_format_arg(float n) noexcept;
explicit basic_format_arg(double n) noexcept;
explicit basic_format_arg(long double n) noexcept;
// Effects: Initializes value with n.
explicit basic_format_arg(const char_type* s);
// Preconditions: s points to a NTCTS (3.37). Effects: Initializes value with s.
template<class traits>
explicit basic_format_arg(basic_string_view<char_type, traits> s) noexcept;
Effects: Initializes value with basic_string_view<char_type>(s.data(), s.size()).
template<class traits, class Allocator>
explicit basic_format_arg(
const basic_string<char_type, traits, Allocator>& s) noexcept;
// Effects: Initializes value with basic_string_view<char_type>(s.data(), s.size()). explicit basic_format_arg(nullptr_t) noexcept;
// Effects: Initializes value with static_cast<const void*>(nullptr).
template<class T> explicit basic_format_arg(T* p) noexcept;
// Constraints: is_void_v<T> is true. Effects: Initializes value with p.
// [Note 1: Constructing basic_format_arg from a pointer to a member is ill-formed unless the user provides an enabled specialization of formatter for that pointer to member type.
explicit operator bool() const noexcept;
// exposition only // exposition only // exposition only // exposition only
// Returns: !holds_alternative<monostate>(value).
// The class handle allows formatting an object of a user-defined type.
namespace std {
template<class Context>
class basic_format_arg<Context>::handle {
const void* ptr_;
void (*format_)(basic_format_parse_context<char_type>&,
Context&, const void*);
template<class T> explicit handle(T&& val) noexcept;
friend class basic_format_arg<Context>;
public:
void format(basic_format_parse_context<char_type>&, Context& ctx) const;
}; }
template<class T> explicit handle(T&& val) noexcept;
// An instance of format-arg-store stores formatting arguments. template<class Context = format_context, class... Args>
format-arg-store<Context, Args...> make_format_args(Args&&... fmt_args);
// Preconditions: The type typename Context::template formatter_type<Ti> meets the BasicFormat-
// Let — TD be remove_cvref_t<T>,
// — const-formattable be true if typename Context::template formatter_type<TD>() .format(declval<const TD&>(), declval<Context&>()) is well-formed, otherwise false,
// — TQ be const TD if const-formattable is true and TD otherwise.
// Mandates: const-formattable || !is_const_v<remove_reference_t<T>> is true.
// Effects: Initializes ptr_ with addressof(val) and format_ with
[](basic_format_parse_context<char_type>& parse_ctx,
Context& format_ctx, const void* ptr) {
typename Context::template formatter_type<TD> f;
parse_ctx.advance_to(f.parse(parse_ctx));
format_ctx.advance_to(f.format(*const_cast<TQ*>(static_cast<const TD*>(ptr)),
format_ctx));
}
void format(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx) const;
// Effects: Equivalent to: format_(parse_ctx, format_ctx, ptr_); template<class Visitor, class Context>
decltype(auto) visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
// Effects: Equivalent to: return visit(forward<Visitor>(vis), arg.value); // 22.14.7.2 Class template format-arg-store [format.arg.store]
namespace std {
template<class Context, class... Args> class format-arg-store {
array<basic_format_arg<Context>, sizeof...(Args)> args;
}; }
// exposition only // exposition only
ter requirements (22.14.6.1) for each Ti in Args.
Returns: An object of type format-arg-store<Context, Args...> whose args data member is initialized with {basic_format_arg<Context>(fmt_args)...}.
template<class... Args>
format-arg-store<wformat_context, Args...> make_wformat_args(Args&&... args);
// Effects: Equivalent to: return make_format_args<wformat_context>(args...);
// 22.14.7.3 Class template basic_format_args [format.args]
}
namespace std {
template<class Context>
class basic_format_args {
size_t size_;
const basic_format_arg<Context>* data_;
public:
basic_format_args() noexcept;
// exposition only // exposition only
}
template<class... Args>
basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
basic_format_arg<Context> get(size_t i) const noexcept;
};
// An instance of basic_format_args provides access to formatting arguments. Implementations should optimize the representation of basic_format_args for a small number of formatting arguments.
// [Note 1: For example, by storing indices of type alternatives separately from values and packing the former.
basic_format_args() noexcept;
// Effects: Initializes size_ with 0. template<class... Args>
basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
// Effects: Initializes size_ with sizeof...(Args) and data_ with store.args.data().
basic_format_arg<Context> get(size_t i) const noexcept;
// Returns: i < size_ ? data_[i] : basic_format_arg<Context>().
// 22.14.8 Class format_error [format.error]
namespace std {
class format_error : public runtime_error {
public:
explicit format_error(const string& what_arg);
explicit format_error(const char* what_arg);
};
// The class format_error defines the type of objects thrown as exceptions to report errors from the formatting library.
format_error(const string& what_arg);
// Postconditions: strcmp(what(), what_arg.c_str()) == 0. format_error(const char* what_arg);
// Postconditions: strcmp(what(), what_arg) == 0.
int main(){
cout << n4910 << endl;
return EXIT_SUCCESS;
}
編纂・実行結果(compile and go)
検討事項(agenda)
コンパイルエラーを取るか、コンパイルエラーの理由を解説する。
参考資料(reference)
関連する自己参照以外は、こちらの先頭に移転。
C言語(C++)に対する誤解、曲解、無理解、爽快。
#include "N4910.h"
C++N4910資料の改善点
dockerにclang
docker gnu(gcc/g++) and llvm(clang/clang++)
コンパイル用shell script C版(clangとgcc)とC++版(clang++とg++)
C++N4910:2022 tag follower 300人超えました。ありがとうございます。
astyle 使ってみた
DoCAP(ドゥーキャップ)って何ですか?
小川メソッド 覚え(書きかけ)
<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>
文書履歴(document history)
ver. 0.01 初稿 20220731