如何设计一个简单的 std::string-to-boost::p osix_time::p time 解析库
How to design a simple std::string-to-boost::posix_time::ptime parsing library
我最近发现需要将std::string
解析为boost::posix_time::ptime
。如何完成此任务的问题在这里得到了很好的回答:如何从字符串中解析日期/时间?
我知道它只需要几行代码(基本上是 istringstream 声明、locale/time_input_facet imbuance 和提取到 ptime),但我想将该功能包装在一个方便的函数中,并使其作为C++库提供给我的各种程序使用 ptimes。
如果可能的话,我想从C++大师那里得到一些关于我的设计的反馈,这样我就可以知道我是否做错了什么,或者是否有更好的方法。特别是,我对语言环境和time_input_facets的工作方式不是很熟悉,所以我希望我没有内存泄漏或任何东西。
在这里:
namespace mydt {
void imbueDTFormat(std::istringstream& iss, const std::string& format );
void parse(const std::string& input, const std::string& format, boost::posix_time::ptime& out ); // (1)
void parse(const std::string& input, std::istringstream& iss, boost::posix_time::ptime& out ); // (2)
void parse(std::istringstream& iss, boost::posix_time::ptime& out ); // (3)
void imbueDTFormat(std::istringstream& iss, const std::string& format ) {
iss.imbue(std::locale(std::locale::classic(), new boost::posix_time::time_input_facet(format) )); // see <http://en.cppreference.com/w/cpp/locale/locale/locale>: "Overload 7 is typically called with its second argument, f, obtained directly from a new-expression: the locale is responsible for calling the matching delete from its own destructor."
} // end imbueDTFormat()
void parse(const std::string& input, const std::string& format, boost::posix_time::ptime& out ) { // (1)
static std::istringstream iss;
imbueDTFormat(iss, format );
parse(input, iss, out );
} // end parse()
void parse(const std::string& input, std::istringstream& iss, boost::posix_time::ptime& out ) { // (2)
// assumes iss has already been imbued with the desired time_input_facet
iss.str(input);
parse(iss, out );
} // end parse()
void parse(std::istringstream& iss, boost::posix_time::ptime& out ) { // (3)
// assumes iss has already been imbued with the desired time_input_facet AND has been initialized with the input str
iss >> out;
} // end parse()
} // end namespace mydt
我写的第一个函数是parse(1)。它提供了最简单的界面;只需传递输入字符串、格式字符串和 ptime OUT var,解析就完成了。它使用静态 istringstream 来完成解析,因此不需要为此进行分配。但是当我在编写函数后查看该函数时,我意识到,如果您有一个重复解析的格式,那么从中重复分配一个新time_input_facet并注入相同的 istringstream 是浪费的。
所以我认为你可以做得更好,让调用代码创建自己的(可能是静态的)istringstream,灌输一次格式,然后反复使用该istringstream进行解析。因此,我为此目的编写了解析(2)。因此,调用代码可以为每种格式提供一个专用函数,如下所示:
void parseServerDT(const std::string& input, boost::posix_time::ptime& out );
void parseHostDT(const std::string& input, boost::posix_time::ptime& out );
// in main, or some other code context
boost::posix_time::ptime serverDT; parseServerDT(getServerDTStr(), serverDT );
boost::posix_time::ptime hostDT; parseHostDT(getHostDTStr(), hostDT );
void parseServerDT(const std::string& input, boost::posix_time::ptime& out ) {
static bool first = true;
static std::istringstream iss;
if (first) {
first = false;
mydt::imbueDTFormat(iss, SERVERDT_FORMAT );
} // end if
mydt::parse(input, iss, out );
} // end parseServerDT()
void parseHostDT(const std::string& input, boost::posix_time::ptime& out ) {
static bool first = true;
static std::istringstream iss;
if (first) {
first = false;
mydt::imbueDTFormat(iss, HOSTDT_FORMAT );
} // end if
mydt::parse(input, iss, out );
} // end parseHostDT()
我认为这种设计应该为调用代码提供最大的便利,并且应该最大限度地减少内存和性能的影响。您可以根据需要定义任意数量的 parseXDT() 函数(甚至可以创建一个宏来减少这些函数中的重复代码)。
任何反馈将不胜感激。谢谢!
至少
-
使静态线程本地。由于缺少编译器,这涉及动态分配它们(这不是问题,因为它是一次性成本)
-
最重要的是,在重复使用之前清除流错误状态和内容
void parseHostDT(const std::string& input, boost::posix_time::ptime& out ) { thread_local std::istringstream* iss = [] { first = false; mydt::imbueDTFormat(iss, HOSTDT_FORMAT); }(); iss->clear(); iss->str(""); mydt::parse(input, iss, out); }
- C++:如何将 unix 时间的字符串转换为 *tm?(使用时间错误:"cannot convert 'String' to 'tm*' ")
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- 使用词法强制转换在'string to double'中设置双精度变量的精度
- 添加 cpp11 插件时出现错误消息"Undefined reference to boost (...)"
- std::string to std::regex
- Copy std::vector to boost::interprocess::vector
- Pointer to boost::thread
- 填充 std::d eque<std::vector<std::string>> with boost::assign::list_of
- 如何 SWIG std::string& to C# ref string
- jni String to *char and java.lang.UnsatisfiedLinkError:
- 如何设计一个简单的 std::string-to-boost::p osix_time::p time 解析库
- Qt equivalent to boost::ptr_vector?
- boost:scoped_ptr to boost::p tr_vector 而不释放资源
- C++ std::string to Ruby VALUE
- C++ CLI System.String^ to MFC LPCTSTR
- 使用C++中的String To Class Lookup表来实例化类
- 创建新文件时std::string to const char*错误
- boost::make_shared<string>() vs boost::make_shared(<string>string( " " ))
- 有没有办法"convert string to vector<int>"?
- std::string to LPOLESTR