Boost.Spirit使用基数将字符串解析为数字

kre*_*ieg 3 c++ boost-spirit boost-spirit-qi

我有一个模板函数,它将字符串转换为数字如下:

template <typename RetType,
    typename Parser =
    typename boost::spirit::traits::create_parser<RetType>::type>
    inline std::enable_if_t<std::is_arithmetic<RetType>::value, RetType>
    cast(const std::string &input)
{
    RetType result;

    if(input.empty())
    {
        // handle this
    }
    auto itBeg = input.cbegin();
    auto itEnd = input.cend();
    if(!bsq::parse(itBeg, itEnd, Parser(), result) || itBeg != itEnd)
    {
        // handle that
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个类似于上面的函数,它将解析表示某个基数中的数字的字符串

template <typename RetType, unsigned Radix,
    typename Parser =
    typename boost::spirit::traits::create_parser<RetType>::type>
    inline std::enable_if_t<std::is_arithmetic<RetType>::value, RetType>
    cast(const std::string &input)
{
    RetType result;

    if(input.empty())
    {
        // handle this
    }
    auto itBeg = input.cbegin();
    auto itEnd = input.cend();
    if(!bsq::parse(itBeg, itEnd, Parser<RetType, Radix, 1 - 1>() /*something like this*/, result) || itBeg != itEnd)
    {
        // handle that
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

当然,解析器是无效的,但是使用基数定义"自动"算术解析器的正确方法是什么?

seh*_*ehe 5

qi::int_parser<>直接使用:

Live On Coliru

#include <boost/spirit/include/qi.hpp>
#include <type_traits>

template <typename RetType, unsigned Radix = 10, typename Parser = typename boost::spirit::qi::int_parser<RetType, Radix> >
inline typename std::enable_if<std::is_arithmetic<RetType>::value, RetType>::type
    cast(const std::string &input)
{
    RetType result;

    if(input.empty())
    {
        // handle this
    }
    auto itBeg = input.cbegin();
    auto itEnd = input.cend();
    if(!boost::spirit::qi::parse(itBeg, itEnd, Parser(), result) || itBeg != itEnd)
    {
        // handle that
        throw "oops";
    }

    return result;
}

int main() {
    std::cout << cast<int>    ("10") << "\n";
    std::cout << cast<int,  2>("10") << "\n";
    std::cout << cast<int,  8>("10") << "\n";
    std::cout << cast<int, 16>("10") << "\n";
    std::cout << cast<int, 16>("ee") << "\n";
}
Run Code Online (Sandbox Code Playgroud)

打印

10
2
8
16
238
Run Code Online (Sandbox Code Playgroud)

提示:非常精确,你可能要检测无/有符号类型,并使用uint_parser<>相应的

  • 你为什么不在问题中提到这个问题(以及你的原因)?对于实数,没有流行的基数文本表示.我想,将real_policy拼凑起来并不难. (2认同)