你知道boost :: fusion库使用的任何好的资源/文章/例子吗?
Boost Fusion看起来非常有趣,我想我理解它是如何工作的以及如何使用基础知识,但我正在寻找一些资源来展示任何有趣的用法/实践,例如文章或博客(除了boost.org本身).
我正在从文件中读取对象的类型:
enum class type_index { ... };
type_index typeidx = read(file_handle, type_index{});
Run Code Online (Sandbox Code Playgroud)
根据类型索引,我想创建一个类型(在可能的类型列表中),并使用它做一些通用的(每种类型的相同通用代码):
std::tuple<type1, type2, ..., typeN> possible_types;
boost::fusion::for_each(possible_types, [&](auto i) {
if (i::typeidx != typeidx) { return; }
// do generic stuff with i
});
Run Code Online (Sandbox Code Playgroud)
那是:
这感觉就像switch具有运行时条件的语句,但是在编译时生成"案例".特别是,这根本不是一个for_each声明(我没有为vector,tuple,list中的所有元素做任何事情,而只是对单个元素做任何事情).
有更好的方式来表达/写出这个成语吗?(例如mpl::vector,std::tuple对于可能的类型使用an 而不是a ,使用与for_each算法不同的东西,...)
我一直在尝试使用一些boost融合的东西来编写一个常规的c struct to file.XML文件似乎是捕获数据并使其与其他工具兼容或手动编辑的好方法.看起来我几乎拥有它,但似乎缺少一些基本的东西.我使用的东西非常类似于boost :: fusion快速入门页面上的内容:http://www.boost.org/doc/libs/1_54_0/libs/fusion/doc/html/fusion/quick_start.html.作为旁注,我已经仔细查看了这里和boost的文档,但似乎没有人访问字段名称.
struct print_xml
{
template <typename T>
void operator()(T const& x) const
{
std::cout
<< '<' << x.first << '>'
<< x
<< "</" << x.first << '>'
;
}
};
Run Code Online (Sandbox Code Playgroud)
我想用它如下:
BOOST_FUSION_ADAPT_STRUCT(
myStructType,
(double, val1)
(double, val2)
(char, letter)
(int, number)
)
myStructType saveMe = { 3.4, 5.6, 'g', 9};
for_each(saveMe, print_xml());
Run Code Online (Sandbox Code Playgroud)
其他时候我将结构定义如下,但仍然没有运气:
namespace fields{
struct val1;
struct val2;
struct letter;
struct number;
}
typedef fusion::map<
fusion::pair<fields::val1, double>,
fusion::pair<fields::val2, double>, …Run Code Online (Sandbox Code Playgroud) 我是boost :: fusion和boost :: mpl库的新手.有谁能告诉我这两个图书馆之间的主要区别?
直到现在我只使用fusion :: vector和其他一些简单的东西.现在我想使用fusion :: map或MPL :: map,但我不知道如何选择正确的.
我需要地图简单类型到复杂类型(类型alisa).目前我有以下片段,这两个工作正是我需要的.
提高::融合:
typedef boost::fusion::map<
boost::fusion::pair<AliasNames::test1,int>,
boost::fusion::pair<AliasNames::test2,double>,
boost::fusion::pair<AliasNames::test3,float>
> TmapAssociations1;
typedef boost::fusion::result_of::value_at_key<TmapAssociations,AliasNames::test1>::type t;
Run Code Online (Sandbox Code Playgroud)
提高:: MPL:
typedef boost::mpl::map<
boost::mpl::pair<AliasNames::test1,int>,
boost::mpl::pair<AliasNames::test2,double>,
boost::mpl::pair<AliasNames::test3,float>
> TmapAssociations2;
boost::mpl::at<TmapAssociations2,AliasNames::test1>::type t2;
Run Code Online (Sandbox Code Playgroud)
MPL和融合之间有什么区别吗?是否存在一个库优先于另一个库的情况?
谢谢你的答复.
我一直在使用GADT在Haskell中创建一个完全类型化的DSEL,对于一个完全类型安全的AST,似乎做一个正确类型的编译器需要构造,例如从Haskell类型到类型和值(类型环境)的映射并且可以通过Haskell类型系统理解.C++具有Boost.Fusion库,其中包含类似这些结构(类型 - >值映射,类型值向量等).Data.Tuple负责处理序列,但是有没有像Boost.Fusion这样的Haskell版本的东西map?
我正在使用QI和Phoenix,我想编写一个返回4个bool的小语法,它将用作语义动作中函数调用的参数.
我有几个需要这些东西的函数,到目前为止我已经使用过这种方法:
( qi::_bool >> qi::_bool >> qi::_bool >> qi::_bool)
[px::bind(&Bool4Function, spirit::_val, spirit::_1, spirit::_2, spirit::_3, spirit::_4)]
Run Code Online (Sandbox Code Playgroud)
虽然它可以自己使用它,但是在整个地方使用它只是简单的丑陋和混乱,即使使用'命名空间部分.
这就是为什么我想把这个表达式提取成一个独立的语法.
所以我尝试了这个(信用证转到ildjarn测试床):
///// grammar implementation /////
#include <boost/fusion/include/vector10.hpp>
#include <boost/spirit/include/qi_bool.hpp>
#include <boost/spirit/include/qi_char_.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi_operator.hpp>
#include <boost/spirit/include/qi_rule.hpp>
#include <boost/spirit/include/qi_string.hpp>
struct FourBools : boost::spirit::qi::grammar<
char const*,
boost::fusion::vector4<bool, bool, bool, bool>()
>
{
typedef boost::fusion::vector4<bool, bool, bool, bool> attribute_type;
FourBools() : base_type(start_)
{
using boost::spirit::bool_;
start_
= "4bools:"
>> bool_ >> ','
>> bool_ >> ','
>> bool_ >> ','
>> bool_ >> ';' …Run Code Online (Sandbox Code Playgroud) 我正在使用Boost :: Spirit将一些文本解析为结构.这需要使用BOOST_FUSION_ADAPT_STRUCT来解析文本并直接存储到结构中.我知道宏有两个参数:结构名称为第一个arg,所有结构成员为第二个参数.而我正在通过那些2.但我得到编译错误说,
error: macro "BOOST_FUSION_ADAPT_STRUCT_FILLER_0" passed 3 arguments, but takes just 2
Run Code Online (Sandbox Code Playgroud)
这是代码片段.如果您需要整个代码,请告诉我.
谢谢.
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
struct Dir_Entry_Pair
{
std::string dir;
std::string value1;
std::pair<std::string, std::string> keyw_value2;
};
}
BOOST_FUSION_ADAPT_STRUCT(
client::Dir_Entry_Pair,
(std::string, dir)
(std::string, value1)
(std::pair< std::string, std::string >, keyw_value2))
Run Code Online (Sandbox Code Playgroud)
这是我试图解析的规则,
qi::rule<Iterator, Dir_Entry_Pair()> ppair = dir
>> '/'
>> entry
>> -(keyword >> entry);
Run Code Online (Sandbox Code Playgroud) 两个stackoverflow 答案建议使用fusion adapt_struct迭代结构字段的方法.这种方法看起来不错.但是,如何迭代到一个本身就是结构的字段?
根据之前的答案,我想出了下面的代码.问题出在代码无法编译的"#if 0"子句中.作为替代解决方案,我创建了"decode()"函数来获取指向目标参数的void指针.这有效,但在编译时丢失了类型信息.有更好的解决方案吗?
struct Foo_s { int i; };
BOOST_FUSION_ADAPT_STRUCT( Foo_s, (int, i) )
struct Bar_s { int v; Foo_s w; };
BOOST_FUSION_ADAPT_STRUCT( Bar_s, (int, v) (Foo_s, w) )
struct AppendToTextBox {
template <typename T> void operator()(T& t) const {
int status = 0;
const char *realname = abi::__cxa_demangle(typeid(t).name(), 0, 0, &status);
printf(" typename: %s value: %s realname: %s\n", typeid(t).name(),
boost::lexical_cast<std::string>(t).c_str(), realname);
std::string rn(realname);
if ( rn.rfind("_s") == rn.size()-2 ) {
#if 0 /* this can …Run Code Online (Sandbox Code Playgroud) c++ reflection introspection boost-fusion template-meta-programming
我有一个关于Spirit Qi的编译问题,它抱怨value_type不是标识符的成员.出于某种原因,Qi的属性系统将标识符视为容器类型,并尝试枚举它的值类型.
这是与此问题类似的问题,但是,我认为原因是单个成员结构,可能与此错误有关.
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
using namespace boost::spirit::qi;
struct identifier
{
std::wstring name;
};
struct problem
{
identifier _1;
identifier _2;
identifier _3;
};
BOOST_FUSION_ADAPT_STRUCT(
identifier,
(std::wstring, name)
)
BOOST_FUSION_ADAPT_STRUCT(
problem,
(identifier, _1)
(identifier, _2)
(identifier, _3)
)
int main(int argc, char* argv[])
{
rule<std::wstring::const_iterator, identifier()> gr_identifier = eps >> raw[lexeme[(alpha | '_') >> *(alnum | '_')]];
// Ok, compiles
/*rule<std::wstring::const_iterator, problem()> gr_problem = gr_identifier
>> …Run Code Online (Sandbox Code Playgroud) 我这里有一个通用状态机的专有实现,它使用std::tr1::tuple一个转换表作为转换表:
template<State StartState, Event TriggerEvent, State TargetState>
struct transition {...};
typedef std::tr1::tuple< transition< ready , run , running >
, transition< running , terminate, terminating >
, transition< terminating, finish , terminated >
> transition_table;
Run Code Online (Sandbox Code Playgroud)
有一个功能
template<typename Transitions>
State find_next_state( State current
, Event event
, const Transitions& transition_table );
Run Code Online (Sandbox Code Playgroud)
在给定当前状态和事件的情况下查找转换表中的下一个状态.
这一切都很好,除了这个平台的tuple实现不支持10个以上的项目.这似乎也是如此boost::tuple,所以我试图改为使用boost::fusion::vector.但似乎融合find_if仅采用"一元MPL Lambda表达式 " - 我想这只能在编译时使用.
所以鉴于上述情况,我该如何实施find_next_state()?
注意:
这是一个专有的嵌入式平台,仅提供GCC 4.1.2,因此我们坚持使用C++ 03 + TR1.
boost-fusion ×10
c++ ×8
boost ×3
templates ×2
boost-mpl ×1
boost-spirit ×1
c++03 ×1
haskell ×1
map ×1
reflection ×1