如何在不提供有效生成器的情况下调用 boost::karma::rule 不消耗其属性
How to tel a boost::karma::rule not to consume its attribute without providing a valid generator?
假设我们有以下源代码:
#include <iostream>
#include <string>
#include <iterator>
#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;
template <typename OutputIterator> struct grammar : karma::grammar<OutputIterator, std::nullptr_t()> {
grammar() : grammar::base_type(query) {
query = "yeah";
}
karma::rule<OutputIterator, std::nullptr_t()> query;
};
int main(void) {
typedef std::back_insert_iterator<std::string> iterator_type;
std::string generated;
iterator_type output_it(generated);
//keys_and_values<sink_type> g;
grammar<iterator_type> g;
bool result = karma::generate(output_it, g, nullptr);
std::cout << result << ":" << generated << std::endl;
return 0;
}
这无法编译,因为karma
缺少一些std::nullptr_t
的特征(这些特征是boost::spirit::traits::extract_c_string
和boost::spirit::traits::char traits
)。更具体地说,它失败是因为karma
无法找到类型为 std::nullptr_t
的属性的生成器。
我看到了几种应对方法:
- 在语法定义中将
std::nullptr_t
替换为karma::unused_type
:它适用于此示例,但可能会在更复杂的语法中引入歧义。 - 定义特征专业化:在我看来,这是肮脏的,而不是通用的。另外,它暴露了我对每个人的标准类型的专业化,导致潜在的冲突。 专用
- 属性转换 :仅为我专用标准类型的相同问题。
- 编写自定义生成器 :迄今为止最好的候选者,但与任务复杂性相比,它会产生大量高度模板化的代码行。
- 放置具有
karma::unused_type
属性的中间规则。一个有效的快速修复,但没有意义。
问题:我如何告诉karma::rule
生成一个简单的文字,而不关心是否为其属性设置生成器?
你似乎偶然发现了臭名昭著的单元素融合序列难题[1]的反面:(
我注意到了,因为错误来自试图验证输入字符串是否与属性 (lit.hpp) 匹配的代码:
// fail if attribute isn't matched by immediate literal
typedef typename attribute<Context>::type attribute_type;
typedef typename spirit::result_of::extract_from<attribute_type, Attribute>::type
extracted_string_type;
using spirit::traits::get_c_string;
if (!detail::string_compare(
get_c_string(
traits::extract_from<attribute_type>(attr, context))
, get_c_string(str_), char_encoding(), Tag()))
{
return false;
}
但是,这根本没有意义,因为文档指出:
lit
和string
一样,也会发出一串字符。主要区别在于lit
不消耗属性。像"hello"
或std::basic_string
这样的普通字符串等效于lit
所以我只是...心血来潮地想稍微胁迫一下,使用与 Qi 侧单元素融合序列相同的解决方法:
query = karma::eps << "yeah";
而且,瞧:它有效:住在科里鲁
[1] 参见
- 如何在具有提升精神的 AST 中使用只有一个属性的类?
- 单成员结构体的灵气属性传播问题
- 使用BOOST_FUSION_ADAPT_STRUCT调整结构时编译器错误
- 将包含字符串成员作为合成属性的类调整
等。这是一个可悲的缺陷,可能需要为SpiritV2解决。
可能的答案 : 发布此内容后,我找到了暂时令我满意的解决方案。那就是:引入一个中间规则。
template <typename OutputIterator> struct grammar : karma::grammar<OutputIterator, std::nullptr_t()> {
grammar() : grammar::base_type(query) {
query = null_rule;
null_rule = "null";
}
karma::rule<OutputIterator, std::nullptr_t()> query;
karma::rule<OutputIterator, karma::unused_type()> null_rule;
};
我仍然对任何评论、责备或其他解决方案感兴趣。
相关文章:
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- boost::spirit::karma 替代生成器,带有 boost::variant 由字符串和字符串别名组成
- boost :: Spirit :: Karma语法:逗号从结构上划定了带有选件属性的输出
- Boost Karma:当boost ::可选时,生成默认文本
- 使用Boost Karma打印boost :: posix_time :: time_duration
- 编译boost.spirit.karma示例,customize_embedded_container.cpp失败
- 使用Boost Karma替换STD :: stringstream double到STD :: String Conv
- Boost Karma对象方法调用
- 如何从boost karma生成c++数组
- 如何在生成boost::spirit::karma时避免boost::phoenix
- 如何访问boost::spirit::karma中嵌套对象的数据
- 使用boost::karma格式化纬度/经度字符串
- 如何在不提供有效生成器的情况下调用 boost::karma::rule 不消耗其属性