【发布时间】:2018-02-08 16:37:35
【问题描述】:
我正在尝试在 Karma 生成器中的 boost::optional 中使用 boost::variant。我已经能够将问题简化为:
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 和boost::optional 兼容,但对我来说问题是“为什么要确保它们完全兼容?”
我怎样才能做到这一点?
【问题讨论】:
-
两件事。 1. 我不禁注意到您仍然忽略了微小的位/只是/使您的代码不是自包含的(这里没有多少人知道要包含哪些标头)。另外,2. 我看到你问了很多问题,也许你可以查看你收到的答案并投票/接受那些值得的答案。
-
我将在以后的问题中包含标题。我总是赞成!
标签: c++ boost boost-spirit boost-spirit-karma