повысить дух генерации кармы на основе входов класса

Привет, что я хочу, чтобы сгенерировать текст в соответствии с тем, что я передаю в генератор, например,

struct C1
{
int Getter()
{
return 3;
}
};

struct C2
{
int Getter()
{
return 5;
}
};template<typename Iterator>
struct Temp:
public karma::grammar<Iterator,boost::variant<C1*,C2*>()>
{
Temp():
Temp::base_type(start1)
{
using karma::int_;
using karma::float_;
using karma::lit;

start1 = c1 | c2;
c1 = karma::lazy(boost::phoenix::bind(&C1::Getter,karma::_1));
c2 = karma::lazy(boost::phoenix::bind(&C2::Getter,karma::_1));

}

karma::rule<Iterator,boost::variant<C1*,C2*>()> start1;
karma::rule<Iterator,C1*() > c1;
karma::rule<Iterator,C2*() > c2;


а затем вызвать что-то вроде

std::string str;
std::back_insert_iterator<std::string> out(str);
Temp<std::back_insert_iterator<std::string> > bla;
C1 c1;
karma::generate(out, bla,&c1);

Я даже не уверен, что использую правильный генератор, но он говорит, что ленивый способен преобразовывать то, что находится в атрибутах, во что-то, что возвращает функтор внутри

2

Решение

Самое простое исправление будет

c1 = int_ [ karma::_1 = boost::phoenix::bind(&C1::Getter,karma::_val) ];
c2 = int_ [ karma::_1 = boost::phoenix::bind(&C2::Getter,karma::_val) ];

BOOST_FUSION_ADAPT_ADT

Я думаю, что вы хотели бы узнать о BOOST_FUSION_ADAPT_ADT () тоже:

struct C1 { int Getter() const { return 3; } void Setter(int){} };
struct C2 { int Getter() const { return 5; } void Setter(int){} };

BOOST_FUSION_ADAPT_ADT(C1, (int,int,obj.Getter(),obj.Setter(val)));
BOOST_FUSION_ADAPT_ADT(C2, (int,int,obj.Getter(),obj.Setter(val)));

Альтернатива 1: attr_cast

использование attr_cast и передать по значению. Вот пример без грамматики для краткости:

using namespace karma;
std::cout << karma::format("C1:" << attr_cast<C1>(int_) | "C2:" << attr_cast<C2>(int_), c1) << "\n";
std::cout << karma::format("C1:" << attr_cast<C1>(int_) | "C2:" << attr_cast<C2>(int_), c2) << "\n";

Какие отпечатки

C1:3
C2:5

Альтернатива 2: с грамматикой / правилами

typedef boost::variant<C1,C2> Var;

template<typename Iterator>
struct Generator: public karma::grammar<Iterator,Var()>
{
Generator(): Generator::base_type(start)
{
using namespace karma;

start = "grammar: " << (c1 | c2);
c1 = "C1:" << attr_cast<int>(int_);
c2 = "C2:" << attr_cast<int>(int_);
}

private:
karma::rule<Iterator,Var()> start;
karma::rule<Iterator,C1()> c1;
karma::rule<Iterator,C2()> c2;
};

Полный пример, который показывает обе альтернативы без: http://liveworkspace.org/code/JWB9B$0:

#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace karma = boost::spirit::karma;
namespace phx   = boost::phoenix;

struct C1 { int Getter() const { return 3; } void Setter(int){} };
struct C2 { int Getter() const { return 5; } void Setter(int){} };

BOOST_FUSION_ADAPT_ADT(C1, (int,int,obj.Getter(),obj.Setter(val)));
BOOST_FUSION_ADAPT_ADT(C2, (int,int,obj.Getter(),obj.Setter(val)));

typedef boost::variant<C1,C2> Var;

template<typename Iterator>
struct Generator: public karma::grammar<Iterator,Var()>
{
Generator(): Generator::base_type(start)
{
using namespace karma;

start = "grammar: " << (c1 | c2);
c1 = "C1:" << attr_cast<int>(int_);
c2 = "C2:" << attr_cast<int>(int_);
}

private:
karma::rule<Iterator,Var()> start;
karma::rule<Iterator,C1()> c1;
karma::rule<Iterator,C2()> c2;
};

typedef boost::spirit::ostream_iterator It;

int main()
{
C1 c1;
C2 c2;

using namespace karma;
std::cout << karma::format("C1:" << attr_cast<C1>(int_) | "C2:" << attr_cast<C2>(int_), c1) << "\n";
std::cout << karma::format("C1:" << attr_cast<C1>(int_) | "C2:" << attr_cast<C2>(int_), c2) << "\n";

// or using a grammar:
Generator<It> bla;
std::cout << karma::format(bla, Var(c1)) << "\n";
std::cout << karma::format(bla, Var(c2)) << "\n";
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector