Proposed resolution:
This wording is relative to N4849.
Change [format.string.general] as follows:
-1- A format string for arguments args is a (possibly empty) sequence of replacement fields, escape sequences, and characters other than { and }. […]
-2- 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.
[…]
-5- 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. […]
Before [format.functions] insert a new sub-clause as indicated:
20.20.? 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 [res.on.exception.handling].
Modify [format.functions] as indicated:
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);[…]-6- […]
-7- Throws:
format_error if fmt is not a format stringAs specified in [format.err.report].template<class Out> Out vformat_to(Out out, string_view fmt, format_args_t<Out, char> args); template<class Out> Out vformat_to(Out out, wstring_view fmt, format_args_t<Out, wchar_t> args); template<class Out> Out vformat_to(Out out, const locale& loc, string_view fmt, format_args_t<Out, char> args); template<class Out> Out vformat_to(Out out, const locale& loc, wstring_view fmt, format_args_t<Out, wchar_t> args);[…][…]
-15- Throws:
format_error if fmt is not a format stringAs specified in [format.err.report].template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, string_view fmt, const Args&... args); template<class Out, class... Args> format_to_n_result<Out> format_to_n(Out out, iter_difference_t<Out> n, wstring_view fmt, const 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, string_view fmt, const 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, wstring_view fmt, const Args&... args);[…][…]
-21- Throws:
format_error if fmt is not a format stringAs specified in [format.err.report].template<class... Args> size_t formatted_size(string_view fmt, const Args&... args); template<class... Args> size_t formatted_size(wstring_view fmt, const Args&... args); template<class... Args> size_t formatted_size(const locale& loc, string_view fmt, const Args&... args); template<class... Args> size_t formatted_size(const locale& loc, wstring_view fmt, const Args&... args);[…]
-25- Throws:
format_error if fmt is not a format stringAs specified in [format.err.report].