最も簡単な修正は
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;
};
out を使用しない両方の方法を示す完全なサンプルは、 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";
}