📄 quick_start.qbk
字号:
[/============================================================================== Copyright (C) 2001-2007 Joel de Guzman, Dan Marsden, Tobias Schwinger Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)===============================================================================/][section Quick Start]I assume the reader is already familiar with tuples (__tuple__) and itsancestor `std::pair`. The tuple is a generalization of `std::pair` formultiple heterogeneous elements (triples, quadruples, etc.). The tuple ismore or less a synonym for fusion's `__vector__`.For starters, we shall include all of Fusion's __sequence__(s) [footnote Thereare finer grained header files available if you wish to have more controlover which components to include (see section __organization__ fordetails).]: #include <boost/fusion/sequence.hpp> #include <boost/fusion/include/sequence.hpp>Let's begin with a `__vector__` [footnote Unless otherwise noted, components arein namespace `boost::fusion`. For the sake of simplicity, code in thisquick start implies `using` directives for the fusion components we will beusing.]: __vector__<int, char, std::string> stuff(1, 'x', "howdy"); int i = __at_c__<0>(stuff); char ch = __at_c__<1>(stuff); std::string s = __at_c__<2>(stuff);Just replace `tuple` for `__vector__` and `get` for `__at_c__` and this is exactlylike __tuple__. Actually, either names can be used interchangeably. Yet,the similarity ends there. You can do a lot more with Fusion `__vector__` or`tuple`. Let's see some examples.[heading Print the vector as XML]First, let's include the algorithms: #include <boost/fusion/algorithm.hpp> #include <boost/fusion/include/algorithm.hpp>Now, let's write a function object that prints XML of the form <type>data</type>for each member in the tuple. struct print_xml { template <typename T> void operator()(T const& x) const { std::cout << '<' << typeid(x).name() << '>' << x << "</" << typeid(x).name() << '>' ; } };Now, finally: __for_each__(stuff, print_xml());That's it! `__for_each__` is a fusion algorithm. It is a generic algorithmsimilar to __stl__'s. It iterates over the sequence and calls a usersupplied function. In our case, it calls `print_xml`'s `operator()` foreach element in `stuff`.[caution The result of `typeid(x).name()` is platform specific. The codehere is just for exposition. Of course you already know that :-)]`__for_each__` is generic. With `print_xml`, you can use it to print just aboutany Fusion __sequence__.[heading Print only pointers]Let's get a little cleverer. Say we wish to write a /generic/ functionthat takes in an arbitrary sequence and XML prints only those elementswhich are pointers. Ah, easy. First, let's include the `is_pointer` boosttype trait: #include <boost/type_traits/is_pointer.hpp>Then, simply: template <typename Sequence> void xml_print_pointers(Sequence const& seq) { __for_each__(__filter_if__<boost::is_pointer<_> >(seq), print_xml()); }`__filter_if__` is another Fusion algorithm. It returns a __filter_view__,a conforming Fusion sequence. This view reflects only those elements thatpass the given predicate. In this case, the predicate is`boost::is_pointer<_>`. This "filtered view" is then passed to the__for_each__ algorithm, which then prints the "filtered view" as XML.Easy, right?[heading Associative tuples]Ok, moving on...Apart from `__vector__`, fusion has a couple of other sequence types to choosefrom. Each sequence has its own characteristics. We have `__list__`, `__set__`,`__map__`, plus a multitude of `views` that provide various ways to present thesequences.Fusion's `__map__` associate types with elements. It can be used as a clevererreplacement of the `struct`. Example: namespace fields { struct name; struct age; } typedef __map__< __fusion_pair__<fields::name, std::string> , __fusion_pair__<fields::age, int> > person;`__map__` is an associative sequence. Its elements are Fusion pairs which differsomewhat from `std::pair`. Fusion pairs only contain one member, with the type oftheir second template parameter. The first type parameter of the pair is used as anindex to the associated element in the sequence. For example, given a `a_person`of type, `person`, you can do: using namespace fields; std::string person_name = __at_key__<name>(a_person); int person_age = __at_key__<age>(a_person);Why go through all this trouble, you say? Well, for one, unlike the`struct`, we are dealing with a generic data structure. There are amultitude of facilities available at your disposal provided out of the boxwith fusion or written by others. With these facilities, introspectioncomes for free, for example. We can write one serialization function (well,two, if you consider loading and saving) that will work for all your fusion`__map__`s. Example: struct saver { template <typename Pair> void operator()(Pair const& data) const { some_archive << data.second; } }; template <typename Stuff> void save(Stuff const& stuff) { __for_each__(stuff, saver()); }The `save` function is generic and will work for all types of `stuff`regardless if it is a `person`, a `dog` or a whole `alternate_universe`.[heading Tip of the Iceberg]And... we've barely scratched the surface! You can compose and expand thedata structures, remove elements from the structures, find specific datatypes, query the elements, filter out types for inspection, transform datastructures, etc. What you've seen is just the tip of the iceberg.[endsect]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -