Say we have the following source code:
#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;
}
This fails to compile because karma
lacks some traits for std::nullptr_t
(those are boost::spirit::traits::extract_c_string
and boost::spirit::traits::char traits
). More specifically, it fails because karma
is not able to find a generator for an attribute of type std::nullptr_t
.
I see several ways to cope with that:
- Replace
std::nullptr_t
bykarma::unused_type
in the grammar definition : It works on this example but may introduce ambiguity in a more complex grammar. - Defining the traits specialization : In my opinion, this is dirty and not generic. Plus, it exposes my specialization of a standard type for everyone, leading to potential conflicts.
- Specializing an attribute transform : Same problem of specializing a standard type just for me.
- Write a custom generator : The best candidate so far, but it makes a serious load of highly templated code lines compared to the task complexity.
- Put a intermediate rule with a
karma::unused_type
attribute. A quick fix that works but have no sense.
Question : How can I tell the karma::rule
to generate a simple literal and not care about having or not a generator for its attribute ?