Re: gcc 4.4.4: std::time_put facet instantiation, and locale imbue-ing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Kalle Olavi Niemitalo writes:

Sam Varshavchik <mrsam@xxxxxxxxxxxxxxx> writes:

I don't understand the logic I'm seeing with libstdc++'s instantiation
of the time_put facet from a locale, and then using the facet to
format a date into an ostream. It appears that time_put's locale gets
ignored. The locale that's imbued in the ostream governs formatting of
date/time localized strings.

I don't have the C++ standard at hand but Josuttis says in "The
C++ Standard Library" (1999) that std::time_put::put can access
other locale facets via its ios_base parameter.  That is what

The same wording is present in 2003.

happens with libstdc++: in <bits/locale_facets_nonio.tcc>, put
and do_put access the non-standard std::__timepunct facet of the
locale imbued in the ios_base, and call that to do the actual
formatting.  When you extract just the std::time_put facet of the
fr_FR.utf-8 locale and tell that to use an ios_base imbued with

Well, that's all I need to do, as far as I know, to format the time and date: extract the std::time_put facet. Aside from using the C library functions that use the global C locale, how else can I format a localized date and time?

the C locale, std::time_put::put then finds the std::__timepunct
facet of the C locale, and the output is not in French.

I understand the general reason for using the imbued locale. std::time_get::get, for example, may need to convert characters to lowercase. It makes sense, in this case then, to get the ctype category facet from the imbued locale. I see the reason for that.

This is what confuses me. It looks like it doesn't matter at all from which locale the std::time_put facet was retrieved from. The formatted output depends solely on the imbued locale. I can just grab a std::time_put facet anywhere I find one, and use it to format localized date and time strings in different locales.

Or, putting it differently: is there anything that std::time_put::do_put() does that it obtains from its own locale? I can't see anything. What's the reason that std::time doesn't take the std::__timepunct facet from its own locale, but gets it from the imbued one.

I suppose the standard permits this behaviour.  It does seem
inconvenient though if you want to construct a locale by mixing
and matching facets from different locales, because you cannot
know in advance which non-standard facets e.g. std::time_put will
need in each implementation of the standard C++ library.

Yes, rereading the standard does seem to suggest it. A lot of the localization stuff is specified as implementation defined. Bummer.

However, if you only want to use a specific locale for a few
output operations, then I think the best option is to construct
a separate std::ios object, just for imbuing it with the desired
locale and then passing it to time_put:

  std::ios format(std::cout.rdbuf());
  format.copyfmt(std::cout);
  format.imbue(l);

  t.put(std::ostreambuf_iterator<char>(std::cout), format, ' ', &tmbuf,
        fmt, fmt+strlen(fmt));

Where did I get t from? Is t l's facet, or any random std::locale's facet?


Attachment: pgpbr2e5AQGVH.pgp
Description: PGP signature


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux