What is the proper use of boost :: fusion :: push_back?

// ... snipped includes for iostream and fusion ... namespace fusion = boost::fusion; class Base { protected: int x; public: Base() : x(0) {} void chug() { x++; cout << "I'm a base.. x is now " << x << endl; } }; class Alpha : public Base { public: void chug() { x += 2; cout << "Hi, I'm an alpha, x is now " << x << endl; } }; class Bravo : public Base { public: void chug() { x += 3; cout << "Hello, I'm a bravo; x is now " << x << endl; } }; struct chug { template<typename T> void operator()(T& t) const { t->chug(); } }; int main() { typedef fusion::vector<Base*, Alpha*, Bravo*, Base*> Stuff; Stuff stuff(new Base, new Alpha, new Bravo, new Base); fusion::for_each(stuff, chug()); // Mutates each element in stuff as expected /* Output: I'm a base.. x is now 1 Hi, I'm an alpha, x is now 2 Hello, I'm a bravo; x is now 3 I'm a base.. x is now 1 */ cout << endl; // If I don't put 'const' in front of Stuff... typedef fusion::result_of::push_back<const Stuff, Alpha*>::type NewStuff; // ... then this complains because it wants stuff to be const: NewStuff newStuff = fusion::push_back(stuff, new Alpha); // ... But since stuff is now const, I can no longer mutate its elements :( fusion::for_each(newStuff, chug()); return 0; }; 

How do I get for_each (newStuff, chug ()) to work?

(Note. I only assume from the too short documentation in boost :: fusion that I have to create a new vector every time I call push_back.)

+4
source share
1 answer

(Note: I rely only on the overly short boost :: fusion documentation that I have to create a new vector every time I call push_back.)

You are not creating a new vector. push_back returns a lazily evaluated view in extended sequence. If you want to create a new vector, then, for example, typedef NewStuff as

 typedef fusion::vector<Base*, Alpha*, Bravo*, Base*, Alpha*> NewStuff; 

Your program then works.

Btw, a merger is a very functional design. I think this will be more merging if you were to store actual objects, not pointers, and use transform . The logic of chug will then be transferred from classes to struct chug , which had a suitable operator() for each type. Then there was no need to create new vectors, you could work with lazily evaluated representations.

+1
source

Source: https://habr.com/ru/post/1309876/


All Articles