gpt4 book ai didi

c++ - 如何设计一个简单的 std::string-to-boost::posix_time::ptime 解析库

转载 作者:太空狗 更新时间:2023-10-29 23:02:34 25 4
gpt4 key购买 nike

我最近发现需要将 std::string 解析为 boost::posix_time::ptime。如何完成这项任务的问题在这里得到了很好的回答:How to parse date/time from string? .

我知道它只需要几行代码(基本上是 istringstream 声明、locale/time_input_facet imbuance 和提取到 ptime),但我想将该功能包装在一个方便的函数中,并将其作为 C++ 库提供我的各种与 ptimes 一起工作的程序。

如果可能的话,我想从 C++ 专家那里得到一些关于我的设计的反馈,这样我就可以知道我是否做错了什么,或者是否有更好的方法。特别是,我不太熟悉 locales 和 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 并将其注入(inject)相同的 istringstream 是一种浪费。

所以我认为您可以通过让调用代码创建自己的(可能是静态的)istringstream 来做得更好,将格式注入(inject)一次,然后重复使用该 istringstream 进行解析。因此,我为此编写了 parse (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() 函数(甚至可以创建一个宏来减少这些函数中的重复代码。)

如有任何反馈,我们将不胜感激。谢谢!

最佳答案

至少

  1. 使静态线程局部化。由于缺少编译器,这涉及动态分配它们(这不是问题,因为这是一次性成本)

  2. 最重要的是,在重新使用之前清除流错误状态和内容

    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++ - 如何设计一个简单的 std::string-to-boost::posix_time::ptime 解析库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27935308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com