Here is a more advanced example that uses a std::time_put facet to print a date. Let us assume we have a date and want to print it this way:
struct std::tm aDate; //1 std::memset(aDate,0,sizeof aDate); //2 aDate.tm_year = 1989; aDate.tm_mon = 9; aDate.tm_mday = 1; std::cout.imbue(std::locale("De_CH")); //3 std::cout << aDate; //4
//1 | A date object is created. It is of type std::tm, which is the time structure defined in <ctime>. |
//2 | The date object is initialized with a particular date, September 1, 1989. |
//3 | Let's assume our program is supposed to run in a German-speaking canton of Switzerland. Hence, we imbue the standard output stream with a German-Swiss locale. |
//4 | The date is printed in German to the standard output stream. |
The output is: 1. September 1989
As there is no operator<<() defined in the C++ Standard Library for the time structure tm from the C library, we must provide this inserter ourselves. The following code suggests a way this can be done. If you are not familiar with iostreams, please refer to the iostreams part of this User's Guide.
To keep it simple, the handling of exceptions thrown during the formatting is omitted.
template<class charT, class traits> std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT,traits>& os, const std::tm& date) //1 { std::locale loc = os.getloc(); //2 typedef std::ostreambuf_iterator<charT,traits> outIter_t; //3 const std::time_put<charT,outIter_t>& fac //4 = std::use_facet<std::time_put<charT, outIter_t> >(loc); //5 fac.put(os,os,os.fill(),&date,'x'); //6 return os; }
//1 | This is a typical signature of a stream inserter; it takes a reference to an output stream and a constant reference to the object to be printed, and returns a reference to the same stream. | |||||||||||||||||||||||||
//2 | The stream's locale object is obtained via the stream's member function getloc(). This is the locale object where we expect to find a time-formatting facet object. | |||||||||||||||||||||||||
//3 | We define a type for an output iterator to a stream buffer. Time-formatting facet objects write the formatted output via an iterator into an output container (see the sections on containers and iterators in the C++ Standard Library User's Guide). In principle, this can be an arbitrary container that has an output iterator, such as a string or a C++ array. Here we want the time-formatting facet object to bypass the stream's formatting layer and write directly to the output stream's underlying stream buffer. Therefore, the output container shall be a stream buffer. | |||||||||||||||||||||||||
//4 | We define a variable that will hold a reference to the locale object's std::time_put facet object. The time formatting facet class std::time_put has two template parameters:
| |||||||||||||||||||||||||
//5 | Here we get the time-formatting facet object from the stream's locale via std::use_facet(). | |||||||||||||||||||||||||
//6 | The facet object's formatting service put() is called. Let us see what arguments it takes. Here is the function's interface:
|