Boost Karma:当boost ::可选时,生成默认文本
Boost Karma: generate default text when boost::optional is unset
考虑以下程序:
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_ | '-');
,但这导致汇编错误:
newertive_function.hpp:127:34:错误:没有成员命名 'is_compatible' 'boost :: Spirit ::特质:: compute_compatible_component, int>, boost ::可选,int>>,boost :: Spirit :: Karma :: domain>' 如果(!component_type :: is_compatible(spirit ::特质:: wher(attr_((( ~~~~~~~~~~~~~~~^
我还注意到,如果我删除FooVariant
并制作FooOptional = boost::optional<int>
并更新发电机,则如果将其传递给未设置的可选元件,我会产生崩溃。例如:
int main()
{
FooOptional fo;
std::cout << boost::spirit::karma::format(FooGenerator<>(), fo) << std::endl;
}
这使我相信我正在错误地使用可选生成。正确的方法是什么?
update
调查更多,我发现了一些有趣的东西。我修改的代码是:
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_ | '-');
我在空价值上崩溃。
我同意这似乎不如您所希望。也许务实的简化是将" nil"表示为变体元素类型:
struct Nil final {};
using FooVariant = boost::variant<Nil, std::string, int>;
现在,默认结构的FooVariant
将包含Nil
。规则简单地变为:
start_ = string_ | bsk::int_ | "(unset)";
demo
活在Wandbox上
#include <boost/spirit/include/karma.hpp>
struct Nil final {};
using FooVariant = boost::variant<Nil, std::string, int>;
template<typename OutputIt = boost::spirit::ostream_iterator>
struct FooGenerator : boost::spirit::karma::grammar<OutputIt, FooVariant()>
{
FooGenerator()
: FooGenerator::base_type(start_)
{
namespace bsk = boost::spirit::karma;
string_ = '"' << *('' << bsk::char_("\"") | bsk::print | "\x" << bsk::right_align(2, '0')[bsk::hex]) << '"';
start_ = string_ | bsk::int_ | "(unset)";
}
boost::spirit::karma::rule<OutputIt, std::string()> string_;
boost::spirit::karma::rule<OutputIt, FooVariant()> start_;
};
int main() {
for (auto fo : { FooVariant{}, {FooVariant{42}}, {FooVariant{"HellornWorld!"}} }) {
std::cout << boost::spirit::karma::format(FooGenerator<>(), fo) << std::endl;
}
}
打印
(unset)
42
"Hellox0dx0aWorld!"
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 文本文件中的单词链表
- 如何使用默认参数等选择模板专业化
- 具有默认模板参数的多态类的模板推导失败
- 从命令行c++发送文本文件名
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 如何使用 GTK 3 正确设置默认文本
- ExtTextOut 文本的持续闪烁,在一段时间后,文本将恢复为默认字体
- Boost Karma:当boost ::可选时,生成默认文本
- 如何在Windows中将使用Qt制作的记事本设置为默认文本编辑器
- 如何在C Win32 GUI中为文本框设置默认背景(灰色)文本
- 如何在 DirectWrite 中使用默认 UI 字体绘制文本
- 更改崇高文本的默认输入源
- 使用 C++ 获取默认的 Windows 文本编辑器.exe路径
- Win32:设置富编辑的默认字体和文本颜色
- 如何在wxRitchTextCtrl中更改文本的默认颜色
- 设置新文件默认文本
- 在变量上显示默认文本,用户可以在C++命令行程序上编辑这些变量
- 为什么默认情况下全局命名空间中没有 C++14 个标准定义的文本?
- 具有透明文本背景而不是默认白色的树视图节点