假设我们有以下源代码:
#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
无法找到 type 属性的生成器std::nullptr_t
。
我看到了几种解决方法:
- 在语法定义中替换
std::nullptr_t
为karma::unused_type
:它适用于此示例,但可能会在更复杂的语法中引入歧义。 - 定义特征专业化:在我看来,这是肮脏的而不是通用的。另外,它暴露了我对每个人的标准类型的专业化,导致潜在的冲突。
- 专门化属性转换:专门为我专门化标准类型的问题。
- 编写自定义生成器:迄今为止最好的候选者,但与任务复杂性相比,它会产生大量高度模板化的代码行。
- 放置一个带有
karma::unused_type
属性的中间规则。一个有效但没有意义的快速修复。
问题:我如何告诉karma::rule
生成一个简单的文字而不关心它的属性是否有生成器?