我正在尝试在 Karma 生成器中使用 a boost::variant
within a boost::optional
。我已经能够将问题简化为:
using FooVariant = boost::variant<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;
start_ = '[' << ( bsk::int_ | '*' ) << ']';
}
boost::spirit::karma::rule<OutputIt, FooOptional()> start_;
};
int main()
{
FooOptional fop1;
std::cout << boost::spirit::karma::format(FooGenerator<>(), fop1) << std::endl;
FooOptional fop2 = FooVariant{123};
std::cout << boost::spirit::karma::format(FooGenerator<>(), fop2) << std::endl;
}
这里的输出是:
[*]
[*]
这不是我所希望的。
我改变的第一件事就是或多或少地通过更改FooVariant
为进行健全性检查:using FooVariant = int;
. 这输出:
[*]
[123]
并且是我想看到的!所以在我的第一个代码中,变体只有一种类型,所以我尝试添加第二种类型,只是为了看看:
using FooVariant = boost::variant<int, double>;
...
start_ = '[' << ( ( bsk::int_ | bsk::double_ ) | '*' ) << ']';
但随后我们回到:
[*]
[*]
然后我尝试为该变体添加一个专门的规则:
using FooVariant = boost::variant<int, double>;
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::int_ | bsk::double_);
start_ = '[' << ( foovar_ | '*' ) << ']';
}
boost::spirit::karma::rule<OutputIt, FooVariant()> foovar_;
boost::spirit::karma::rule<OutputIt, FooOptional()> start_;
};
int main()
{
FooOptional fop1;
std::cout << boost::spirit::karma::format(FooGenerator<>(), fop1) << std::endl;
FooOptional fop2 = FooVariant{123};
std::cout << boost::spirit::karma::format(FooGenerator<>(), fop2) << std::endl;
}
这给出了编译错误:
alternative_function.hpp:127:34: error: no member named 'is_compatible' in
'boost::spirit::traits::compute_compatible_component<boost::variant<int, double>, boost::optional<boost::variant<int, double> >, boost::spirit::karma::domain>'
if (!component_type::is_compatible(spirit::traits::which(attr_)))
~~~~~~~~~~~~~~~~^
看起来模板生成正在尝试确保boost::variant
andboost::optional
兼容,但对我来说,问题是“为什么要确保它们完全兼容?”
我怎样才能使这项工作?