假设我有一个这样的结构:
struct MyStruct
{
int a;
int b;
int c;
}
BOOST_FUSION_ADAPT_STRUCT
(
MyStruct,
(int, a)
(int, b)
(int, c)
)
然后如果我有一个简单的生成器:
struct MyStructGenerator
: boost::spirit::karma::grammar<boost::spirit::ostream_iterator, MyStruct()>
{
MyStructGenerator() : MyStructGenerator::base_type(start_)
{
namespace bsk = boost::spirit::karma;
start_ = '<'
<< bsk::int_
<< ','
<< bsk::int_
<< ','
<< bsk::int_
<< '>';
}
~MyStructGenerator() = default;
boost::spirit::karma::rule<boost::spirit::ostream_iterator, MyStruct()> start_;
};
然后我运行以下命令:
int main()
{
MyStruct ms = { 3, 2, 1 };
std::cout << boost::spirit::karma::format(MyStructGenerator(), ms) << std::endl;
}
我当然希望看到 <3, 2, 1>
.我想不通的是如何更改规则内的顺序?如果我想看 <1, 2, 3>
怎么办?或者即使我想看 <2, 1, 3>
?
此外,如果没有 BOOST_FUSION_ADAPT_STRUCT
,我是否可以做到这一点? ?
最佳答案
Q1 如果我想看到 <1, 2, 3> 或者即使我想看到 <2, 1, 3>
怎么办?
只需更改适应的顺序:
简化 Live On Wandbox :
#include <boost/fusion/adapted/struct.hpp>
struct MyStruct { int a, b, c; };
BOOST_FUSION_ADAPT_STRUCT(MyStruct, a, b, c)
#include <boost/spirit/include/karma.hpp>
namespace bsk = boost::spirit::karma;
template <typename It = boost::spirit::ostream_iterator>
struct MyGen : bsk::grammar<It, MyStruct()> {
MyGen() : MyGen::base_type(start_) {
using namespace bsk;
start_ = '<' << int_ << ',' << int_ << ',' << int_ << '>';
}
private:
bsk::rule<It, MyStruct()> start_;
};
int main() {
MyGen<> gen;
std::cout << format(gen, MyStruct { 3, 2, 1 }) << "\n";
}
打印 <3,2,1>
, 但是用
BOOST_FUSION_ADAPT_STRUCT(MyStruct, c, b, a)
打印 <1,2,3>
.
Q2 不适应?
嗯。我可以向您展示一些您可能感兴趣的内容:
没有业力: Live On Wandbox :
#include <boost/fusion/adapted/struct.hpp> struct MyStruct { int a, b, c; }; BOOST_FUSION_ADAPT_STRUCT(MyStruct, c, b, a) #include <iostream> #include <boost/fusion/include/io.hpp> #include <boost/fusion/include/as_vector.hpp> using boost::fusion::as_vector; int main() { MyStruct ms { 3, 2, 1 }; std::cout << as_vector(ms) << "\n"; std::cout << boost::fusion::tuple_open("<") << boost::fusion::tuple_delimiter(",") << boost::fusion::tuple_close(">"); std::cout << as_vector(ms) << "\n"; }
打印
(1 2 3) <1,2,3>
命名改编:您可以同时使用
*_NAMED
改编不同的顺序。宏。这是一个演示,展示了它同时使用 Fusion IO 和 Karma 生成器。Note I slightly modified the struct so it's easier to track which field is
'a'
,'b'
or'c'
.查看 Live On Wandbox :
#include <boost/fusion/adapted/struct.hpp> struct MyStruct { char a, b, c; }; BOOST_FUSION_ADAPT_STRUCT_NAMED(MyStruct, AsABC, a, b, c) BOOST_FUSION_ADAPT_STRUCT_NAMED(MyStruct, AsBCA, b, c, a) BOOST_FUSION_ADAPT_STRUCT_NAMED(MyStruct, AsCBA, c, b, a) #include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/qi.hpp> namespace bsk = boost::spirit::karma; template <typename Attr, typename It = boost::spirit::ostream_iterator> struct MyGen : bsk::grammar<It, Attr()> { MyGen() : MyGen::base_type(start_) { using namespace bsk; start_ = '<' << auto_ << ',' << auto_ << ',' << auto_ << '>'; } private: bsk::rule<It, Attr()> start_; }; #include <iostream> #include <boost/fusion/include/io.hpp> #include <boost/fusion/include/as_vector.hpp> using boost::fusion::as_vector; template <typename Attr> void do_tests(Attr const& ms) { std::cout << as_vector(ms) << "\n"; std::cout << format(MyGen<Attr>{}, ms) << "\n"; } int main() { std::cout << boost::fusion::tuple_open("<") << boost::fusion::tuple_delimiter(",") << boost::fusion::tuple_close(">"); MyStruct ms { 'a', 'b', 'c' }; using namespace boost::fusion::adapted; do_tests(AsABC{ms}); do_tests(AsCBA{ms}); do_tests(AsBCA{ms}); }
打印
<a,b,c> <a,b,c> <c,b,a> <c,b,a> <b,c,a> <b,c,a>
是的,你可以不适应(尽管不要):
Live On Wandbox (由于编译时的限制,注释部分)
struct MyStruct { char a, b, c; }; #include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/phoenix.hpp> namespace bsk = boost::spirit::karma; namespace phx = boost::phoenix; template <typename It = boost::spirit::ostream_iterator> struct MyGen : bsk::grammar<It, MyStruct()> { MyGen() : MyGen::base_type(start_) { using boost::proto::deep_copy; using namespace bsk; auto A = deep_copy(char_[ _1 = phx::bind(&MyStruct::a, _val) ]); auto B = deep_copy(char_[ _1 = phx::bind(&MyStruct::b, _val) ]); auto C = deep_copy(char_[ _1 = phx::bind(&MyStruct::c, _val) ]); start_ = '<' << A << ',' << B << ',' << C << '>' << eol << '<' << A << ',' << C << ',' << B << '>' << eol << '<' << B << ',' << A << ',' << C << '>' << eol << '<' << C << ',' << A << ',' << B << '>' << eol << '<' << B << ',' << C << ',' << A << '>' << eol << '<' << C << ',' << B << ',' << A << '>' << eol ; } private: bsk::rule<It, MyStruct()> start_; }; int main() { std::cout << format(MyGen<>{}, MyStruct { 'a', 'b', 'c' }); }
打印
<a,b,c> <a,c,b> <b,a,c> <c,a,b> <b,c,a> <c,b,a>
关于c++ - Boost Karma,重新排序结构元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48646081/