我应该包含哪些 header 文件以便在 boost spirit 中使用 limit_d 指令?

What header files should i include in order to use limit_d directive in boost spirit?

我是初学者boost spirit

我想要做的只是解析一个具有以下格式的时间的文本:

HH:MM::SS

使用以下规则(提升文档)这很容易

uint_parser<int, 10, 2, 2> uint2_p;

r = lexeme_d
    [
        boost::spirit::limit_d(0u, 23u)[uint2_p] >> ':' 
        >>  boost::spirit::limit_d(0u, 59u)[uint2_p] >> ':' 
        >>  boost::spirit::limit_d(0u, 59u)[uint2_p]           
    ];

问题是我收到一个编译器错误,指出 limit_d 不是 boost spirit 命名空间的成员,即使 limit_d 指令位于 boost::spirit 下以下 header:

中的命名空间

boost/spirit/home/classic/core/composite/directives.hpp

我已经包含了这个 header。

所以我很困惑我应该包含哪个 header 以便编译代码(我使用的是 VS2013)

P.S。我的代码在没有 limit_d 指令的情况下工作正常,所以问题肯定是由 limit_d.

引起的

supposed 使用 <boost/spirit/include/...> 中的 header,这样 Boost 可能会在不影响客户端代码的情况下改变其内部结构。

include <boost/spirit/include/classic_directives.hpp> 只是 you 所使用的包装器,但是,因此除了忽略一个之外,您的 header 没有任何问题抽象层。

真正的问题是您使用的命名空间 -- boost::spirit -- 与您使用的应该使用过--boost::spirit::classic.

IIRC,当新的 Spirit v2 API 出来时,他们将以前的 boost::spirit 变成 boost::spirit::classic 几个版本,他们试图修复 Spirit "Header Hell" .

#include <boost/spirit/include/classic_directives.hpp>

namespace bspirit = boost::spirit::classic;

int main()
{
    bspirit::limit_d( 0u, 23u );
}

如果您不担心较长的编译时间并且不想弄清楚 确切地 使用哪个 header,您当然可以简单地 #include <boost/spirit/include/classic.hpp> 并完成它。 ;-)

使用@DevSolar 发布的答案我可以看到 limit_d 但这会引入另一个编译错误,说明我们不能使用

boost::spirit::qi::uint_parser<int, 10, 2, 2> uint2_p;

limit_d 所以我将其更改为

boost::spirit::classic::uint_parser<uint16, 10, 2, 2> uint2_p;

因此,时间解析器规则如下:

boost::spirit::classic::uint_parser<uint16, 10, 2, 2>           uint2_p;
boost::spirit::qi::rule<std::string::const_iterator, Time(), qi::space> Time_;

Time_ = lexeme_d
    [
            boost::spirit::classic::limit_d(0u, 23u)[uint2_p] >> ':'
        >>  boost::spirit::classic::limit_d(0u, 59u)[uint2_p] >> ':'
        >>  boost::spirit::classic::limit_d(0u, 59u)[uint2_p]
    ];

此代码的问题是我们不能将 limit_dBoost::Spirit::QI 一起使用,因为您已经注意到来自 QI 命名空间的规则。

所以我搜索了与 Spirit 2.x

兼容的 limit_d 等价物

here 所述,Spirit limit_d 中没有等效项 2.x,您必须使用语义操作来解决我的问题。

所以工作代码应该是这样的:

    namespace qi = boost::spirit::qi;
    struct Time
    {
        unsigned Hour;
        unsigned Minute;
        unsigned Second;
    };

    boost::spirit::qi::rule<std::string::const_iterator, Time(), qi::space> Time_;

    Time_ = lexeme_d
        [
                    qi::uint_[qi::_pass = (0 <= qi::_1 && qi::_1 <= 23)] >> ':'
                >>  qi::uint_[qi::_pass = (0 <= qi::_1 && qi::_1 <= 59)] >> ':'
                >>  qi::uint_[qi::_pass = (0 <= qi::_1 && qi::_1 <= 59)]
        ];