我需要将两个由空格分隔的无符号整数解析为两个 std::Optional。其中一个或两个都可以是nan。例如,有效输入:“123 456”或“123 nan”或“nan 456”或“nan nan”。最优雅的规则是什么?谢谢!
假设有些事情,
类似
的属性类型using Pair = std::pair<std::optional<int>, std::optional<int>>;
使用灵气
不希望不区分大小写
需要消耗全部输入
在输入中始终需要两个标记,仅当不明确时才需要空格(例如,
1nan
被发现没有空格)
我建议类似的东西
auto optint = qi::copy(qi::int_ | "nan");
qi::rule<It, Pair()> p = qi::skip(qi::space) [ optint >> optint ];
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <optional>
#include <iomanip>
namespace qi = boost::spirit::qi;
using Pair = std::pair<std::optional<int>, std::optional<int>>;
using It = std::string::const_iterator;
template <typename T> std::string display(std::optional<T> const& v) {
return v? std::to_string(v.value()) : "nullopt";
}
static inline std::ostream& operator<<(std::ostream& os, Pair const& pair) {
return os << "(" << display(pair.first) << ", " << display(pair.second) << ")";
}
int main() {
auto optint = qi::copy(qi::int_ | "nan");
qi::rule<It, Pair()> p = qi::skip(qi::space) [ optint >> optint ];
for (std::string const input : {"123 456", "123 nan", "nan 456", "nan nan"}) {
Pair parsed;
if (parse(begin(input), end(input), p >> qi::eoi, parsed)) {
std::cout << quoted(input) << " -> " << parsed << std::endl;
} else {
std::cout << quoted(input) << " -> Did not parse" << std::endl;
}
}
}
印刷
"123 456" -> (123, 456)
"123 nan" -> (123, nullopt)
"nan 456" -> (nullopt, 456)
"nan nan" -> (nullopt, nullopt)