我需要使用其他对象提供的装饰反序列化std::vector<boost::variant<..>>
。
“装饰”启用的一个功能是向量中的空条目。在我的实际实现中,我遇到了一堵砖墙。但是,我已经设法收缩它。编译的代码:
#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>
namespace karma = boost::spirit::karma;
typedef boost::variant<boost::int32_t, boost::int64_t> custom_variant;
int main()
{
using karma::generate;
custom_variant v;
std::string temp;
std::back_insert_iterator<std::string> x(temp);
std::cout << v;
karma::generate(x, karma::auto_, v);
}
违规更改,尝试实施“未定义”类型以及所需的概念。
#include <string>
#include <boost/spirit/include/karma.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>
namespace karma = boost::spirit::karma;
struct undefined{};
std::ostream & operator<<(std::ostream & out, undefined const & undefined)
{
return out;
}
typedef boost::variant<undefined,boost::int32_t, boost::int64_t> custom_variant;
int main()
{
using karma::generate;
custom_variant v;
std::string temp;
std::back_insert_iterator<std::string> x(temp);
std::cout << v;
karma::generate(x, karma::auto_, v);
}
如果我注释掉karma::generate
步骤,std::cout
是一个有效的表达式(Boost :: variant OutputStreamable
)。 Spirit要求生成器的类型为OutputStreamable
(spirit :: karma OutputStreamable
),上面的变体应为OutputStreamable
,因为我已经undefined
类型{{1作为无操作。
是什么给出的? :(
我真的开始质疑天气,当使用带有&gt;的库时,C ++模板机制是值得的。 2级模板间接。也许我应该回到直接c。
修改1:
好的,Clang给了我一个明智的OutputStreamable
错误......
first
现在我想弄清楚如何将undefined映射为无操作以获得干净的转换。这个spirit documentation entry(以及具体的this)描述了我需要研究的内容。是否存在由精神提供的通用未定义类型或者在boost中定义的类型,该精神已经映射为无操作?
编辑2:
error: no type named 'properties' in 'boost::spirit::karma::no_auto_mapping_exists'
开始看起来很有吸引力,因为精神为它们提供了类型推导。
答案 0 :(得分:3)
我建议使用spirit::unused_type
用于此目的,因为它已经为Spirit“已知”并且预定义了operator<<()
(但任何其他类型都可以) - 并非您真正需要首先是Karma的运营商。
此外,您必须为create_generator
提供专业化(如您所怀疑):
namespace boost { namespace spirit { namespace traits
{
template <>
struct create_generator<spirit::unused_type>
{
typedef spirit::karma::eps_type type;
static type call()
{
return spirit::karma::eps;
}
};
}}}
会将unused_type
映射到karma::eps
。这似乎正是你所需要的,因为eps
在没有生成任何东西的情况下吃属性,而总是成功。如果你走这条路线,你将不需要使用optional<>
。