[英]Is there a builtin alternative to std::put_time for GCC <5?
我暫時被困在 GCC4.8 上。 我想將當前時間打印為秒以外的時間。 如果put_time
有效,我的代碼將很簡單,如下所示:
std::cout << std::setw(24) << std::put_time(c_time, "[%T%z %F] ");
如果沒有put_time
,我必須手動訪問c_time
的元素c_time
手動完成所有格式設置,這在 a** 中會很痛苦,如果可能的話,我寧願避免這種情況。 請注意,這並不意味着我永遠不想以任何方式與 C 進行交互,甚至是間接的——如果可能的話,我只想避免直接使用 C 進行編碼。
但是,除了strftime
之外,我找不到std::put_time
任何替代方案,我想避免這種情況,因為它需要幾乎兩倍的代碼行並且難以閱讀,至少對我而言。 此外,這是 C++,而不是 C,所以我想盡可能避開 C 函數。
我錯過了什么嗎? 是否有在 GCC 4.8 下工作的std::put_time
的內置替代方案?
請注意,它不必以完全相同的方式工作——比如說,如果它直接將它打印到輸出,而不是作為一個流操縱器,那也完全沒問題,就像一個返回std::string
的函數一樣std::string
包含格式化的時間。
我已經做了很多谷歌搜索並找到了<chrono>
,但這不起作用,因為它沒有任何可以自動格式化時間的東西。 我仍然必須手動完成,而且我很確定這會更有效,因為我必須將自紀元以來的秒數解析為年、月、日等。
此外,這是 C++,而不是 C,所以我想盡可能避開 C 函數。
這是一種非常愚蠢的心態。 put_time
使用std::strftime
。
返回:未指定類型的對象......其中函數
f
定義為:
template <class charT, class traits>
void f(basic_ios<charT, traits>& str, const struct tm* tmb, const charT* fmt) {
/* ... */
typedef time_put<charT, Iter> TimePut;
/* ... */
}
而time_put
的定義在locale.time.put.virtuals#1 中:
效果:將參數
t
的內容格式化為放置在輸出序列s
上的字符。 格式由參數格式和修飾符控制,解釋為與標准庫函數strftime()
的字符串參數中的格式說明符相同...
另一個解決方案是從后來的 GCC 的頭文件中std::put_time
的定義,因為底層工具std::time_put
仍然存在於 GCC 4.8 中,並且定義不是很復雜。 這是從 GCC 7.4 的<iomanip>
復制的,並為清晰起見進行了編輯:
#if __GNUC__ && __GNUC__ < 5
#include <ostream> // std::basic_ostream
#include <ios> // std::ios_base
#include <locale> // std::use_facet, std::time_put
#include <iterator> // std::ostreambuf_iterator
template<typename CharT>
struct _put_time
{
const std::tm* time;
const char *fmt;
};
template<typename CharT>
inline _put_time<CharT>
put_time(const std::tm* time, const CharT* fmt)
{ return { time, fmt }; }
template<typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits> &os, _put_time<CharT> f)
{
typedef typename std::ostreambuf_iterator<CharT, Traits> Iter;
typedef std::time_put<CharT, Iter> TimePut;
const CharT* const fmt_end = f.fmt + Traits::length(f.fmt);
const TimePut& mp = std::use_facet<TimePut>(os.getloc());
std::ios_base::iostate err = std::ios_base::goodbit;
try {
if (mp.put(Iter(os.rdbuf()), os, os.fill(), f.time, f.fmt, fmt_end).failed())
err |= std::ios_base::badbit;
}
catch (...) {
err |= std::ios_base::badbit;
}
if (err)
os.setstate(err);
return os;
}
#endif
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.