boost::variant<boost::container::vector<int>, std::string> tmp = "test";
std::string use;
namespace karma = boost::spirit::karma;
bool r = karma::generate(std::back_insert_iterator<std::string>(use), +karma::int_ | *karma::char_, tmp);
The result is r = false, use = "". However, I expect use = "test".
There is another example
boost::variant<std::vector<int>, std::string> tmp = "test";
std::string use;
namespace karma = boost::spirit::karma;
bool r = karma::generate(std::back_insert_iterator<std::string>(use), +karma::int_ | +karma::char_, tmp);
The result is still r = false, use = "". However. What' wrong?
There is a big difference between how the alternative parser and alternative generator work. The alternative parser tries to match its operands one by one until one of them succeeds. In contrast the alternative generator uses the operand that matches exactly the attribute you want to generate and if there is none that matches it does nothing. If there are several that do match, those are tried one by one until one of them succeeds. The easiest way to solve your problem is creating karma::rule
s that expose the exact attributes in your variant.
#include <iostream>
#include <vector>
#include <boost/spirit/include/karma.hpp>
#include <boost/container/vector.hpp>
int main()
{
boost::variant<boost::container::vector<int>, std::string> tmp = "test";
std::string use;
namespace karma = boost::spirit::karma;
//Your original code
bool r = karma::generate(std::back_insert_iterator<std::string>(use), +karma::int_ | *karma::char_, tmp);
std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;
//Create rules to expose explicitly the attributes you want
use.clear();
karma::rule<std::back_insert_iterator<std::string>,boost::container::vector<int>()> ints_rule = karma::int_%',';
karma::rule<std::back_insert_iterator<std::string>,std::string()> string_rule = *karma::char_;
r = karma::generate(std::back_insert_iterator<std::string>(use), ints_rule | string_rule, tmp);
std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;
//Same test using ints
use.clear();
boost::container::vector<int> tmp_vector;
tmp_vector.push_back(1);
tmp_vector.push_back(2);
tmp=tmp_vector;
r = karma::generate(std::back_insert_iterator<std::string>(use), ints_rule | string_rule, tmp);
std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;
//An example in which the variant has the exact same attributes exposed by the alternative generator
use.clear();
boost::variant<std::vector<int>, std::vector<char> > tmp2;
std::vector<char> string;
string.push_back('t');
string.push_back('e');
string.push_back('s');
string.push_back('t');
tmp2=string;
r = karma::generate(std::back_insert_iterator<std::string>(use), karma::int_%',' | *karma::char_,tmp2);
std::cout << "r=" << std::boolalpha << r << ", Use: \""<< use << '"' << std::endl;
}