Я экспериментирую с числовым аспектом iostreams / locale и наткнулся на что-то довольно любопытное:
«Канонический пример» использования std :: num_put фасет прямое форматирование числа выглядит так:
std::string f(double value) {
using namespace std;
stringstream ss;
num_put<char> const& npf = use_facet<num_put<char> >(ss.getloc());
npf.put(/*out=*/ss, /*format=*/ss, /*fill=*/' ', value);
return ss.str();
}
первый параметр в put
это вещь, где вывод записывается в.
У нас также может быть такой код, и он работает:
std::string g(double value) {
using namespace std;
stringstream ss;
typedef char* CharBufOutIt;
num_put<char, CharBufOutIt> const& npf = use_facet<num_put<char, CharBufOutIt> >(ss.getloc());
char big_enough_buf[100];
npf.put(/*out=*/big_enough_buf, /*format=*/ss, /*fill=*/' ', value);
return big_enough_buf;
}
второй параметр в put()
является объектом потока, который определяет конкретное форматирование, которое будет применено. Второй параметр не модифицировано совсем. (Не в моей реализации, и не в соответствии с чем документы описывать этот параметр для.)
Тем не менее, подпись put
выглядит так:
iter_type put (iter_type out, станд :: ios_base& str, char_type fill, long
double v) const;
То есть он принимает объект ios_base неконстантная ссылка, даже если это будет выглядеть Const ссылка.
Я что-то пропустил? Это просто (историческая?) Особенность в спецификации C ++ iostreams? Обсуждали ли это когда-либо комитет по стандартизации C ++?
От стандарт (22.4.2.2.2) реализация put
в одной точке как таковой:
Этап 3:
Если
str.width()
ненулевое и числоcharT’s
в последовательности после стадии 2 меньшеstr.width()
затем в последовательность, указанную для заполнения, добавляется достаточное количество символов заполнения, чтобы привести длину последовательности кstr.width()
,str.width(0)
называется
Также, str.width(0)
звонки width
объявлено без const
(увидеть эта ссылка):
streamsize ios_base::width (streamsize wide);
Других решений пока нет …