Boost.Spirit 将字符串解析为带基数的数字
Boost.Spirit parse string to number with radix
我有一个将字符串转换为数字的模板函数,如下所示:
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;
}
现在我想创建一个类似于上面的函数,它将解析表示某个基数的数字的字符串
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;
}
解析器当然是无效的,但是用基数定义"automatic"算术解析器的正确方法是什么?
我会直接使用qi::int_parser<>
:
#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";
}
版画
10
2
8
16
238
Hint: to be very accurate you might want to detect signed/unsigned types and use uint_parser<>
accordingly
我有一个将字符串转换为数字的模板函数,如下所示:
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;
}
现在我想创建一个类似于上面的函数,它将解析表示某个基数的数字的字符串
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;
}
解析器当然是无效的,但是用基数定义"automatic"算术解析器的正确方法是什么?
我会直接使用qi::int_parser<>
:
#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";
}
版画
10
2
8
16
238
Hint: to be very accurate you might want to detect signed/unsigned types and use
uint_parser<>
accordingly