【发布时间】:2018-07-18 04:11:45
【问题描述】:
考虑以下程序:
using FooVariant = boost::variant<std::string, int>;
using FooOptional = boost::optional<FooVariant>;
template<typename OutputIt = boost::spirit::ostream_iterator>
struct FooGenerator
: boost::spirit::karma::grammar<OutputIt, FooOptional()>
{
FooGenerator()
: FooGenerator::base_type(start_)
{
namespace bsk = boost::spirit::karma;
foovar_ = bsk::auto_;
start_ = -foovar_;
}
boost::spirit::karma::rule<OutputIt, FooVariant()> foovar_;
boost::spirit::karma::rule<OutputIt, FooOptional()> start_;
};
int main()
{
FooVariant fv = "foo";
FooOptional fo = fv;
std::cout << boost::spirit::karma::format(FooGenerator<>(), fo) << std::endl;
}
正如预期的那样,这将打印foo。同样,如果我简单地初始化fo:
FooOptional fo;
然后程序将再次按预期打印任何内容。但我不想打印任何内容,而是打印-。因此,我将start_ 的规则更改为:
start_ = (foovar_ | '-');
但这会导致编译错误:
alternative_function.hpp:127:34:错误:没有命名成员 'is_compatible' 在 'boost::spirit::traits::compute_compatible_component, 整数>, boost::optional, int> >, boost::spirit::karma::domain>' if (!component_type::is_compatible(spirit::traits::which(attr_))) ~~~~~~~~~~~~~~~~^^
我还注意到,如果我删除 FooVariant 并改为创建 FooOptional = boost::optional<int> 并更新我的生成器,如果我传递一个未设置的选项,我可能会导致崩溃。例如:
int main()
{
FooOptional fo;
std::cout << boost::spirit::karma::format(FooGenerator<>(), fo) << std::endl;
}
这让我相信我错误地使用了可选生成。这样做的正确方法是什么?
更新
再调查一下,我发现了一些有趣的事情。我修改后的代码是:
using FooVariant = boost::variant<std::string, int>;
using FooOptional = boost::optional<int>;
template<typename OutputIt = boost::spirit::ostream_iterator>
struct FooGenerator
: boost::spirit::karma::grammar<OutputIt, FooOptional()>
{
FooGenerator()
: FooGenerator::base_type(start_)
{
namespace bsk = boost::spirit::karma;
foovar_ = bsk::int_;
start_ = (bsk::int_ | '-');
}
boost::spirit::karma::rule<OutputIt, int()> foovar_;
boost::spirit::karma::rule<OutputIt, FooOptional()> start_;
};
int main()
{
FooOptional fo;
std::cout << boost::spirit::karma::format(FooGenerator<>(), fo) << std::endl;
}
这样做的原因是它将打印- 或一个整数值(如果分配了一个值)(不在粘贴的代码中)。但是,当我将 start_ 规则更改为:
start_ = (foovar_ | '-');
我因空值而崩溃。
【问题讨论】:
标签: c++ boost boost-spirit