comp.lang.c++@googlegroups.com | Google Groups | ![]() |
Unsure why you received this message? You previously subscribed to digests from this group, but we haven't been sending them for a while. We fixed that, but if you don't want to get these messages, send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
- Question about definition of static template member - 1 Update
- Onwards and upwards - 1 Update
- Improving a tutorial on the Visitor pattern - 9 Updates
- Variadic Template in template class - 1 Update
Vir Campestris <vir.campestris@invalid.invalid>: Nov 08 09:52PM On 06/11/2014 21:25, Paavo Helde wrote: > In > particular, the compiler can choose to optimize it fully away For an int (or similar) that's what I'd expect. I tend to use static const... to replace #defines for exactly that reason. If performance ever matters I'll check it still does it. But right now I seem to be writing Java :( Andy |
woodbrian77@gmail.com: Nov 08 01:16PM -0800 On Friday, November 7, 2014 3:49:47 PM UTC-6, Öö Tiib wrote: > The iostream-style chaining of operations is also option. That takes > turning brian's logic from "buf" "giving" things to "stuff" into > "stuff" "taking" things out of "buf". I use "stuff taking things out of buf" approach if it's a class. For example: class cmw_request { marshalling_integer const accountNbr; // ... public: template <class R> explicit cmw_request (ReceiveBuffer<R>& buf) : accountNbr(buf) {} }; I can't do that with primitive types since they don't have constructors. > Also chaining free functions > looks ugly so either he has to make the functions members of "buf" > or to overload operators (like iostream does). For primitive types I've made the functions members of buf. Brian Ebenezer Enterprises |
Paul <pepstein5@gmail.com>: Nov 07 03:23PM -0800 On Friday, November 7, 2014 11:14:04 PM UTC, Paul wrote: > Any ideas of how to resolve this? (Feel free to suggest ideas that break the Visitor pattern). > Thank You, > Paul Sorry, v does not represent a member of the Element hierarchy, of course. I should have said that the code is duplicated regardless of which member of the Element hierarchy is calling accept -- my question still stands, though. |
"Öö Tiib" <ootiib@hot.ee>: Nov 07 06:51PM -0800 On Friday, November 7, 2014 11:14:04 PM UTC, Paul wrote: > below. Presumably the virtual destructor has been incorrectly > omitted, but that might be forgiven because it's not really > relevant to the main point. Looking at 'main' the code has chosen to leak memory instead of messing with destructors anyway. I would avoid reading that site. > However, I am concerned about the code duplication here -- > the line v.visit(this) is just repeated verbatim regardless > of what member of the Element hierarchy v represents. Such double dispatch is needed for to ensure that correct overload from visitor is selected by compiler. There are no "multimethods" in C++ and so such duplicated one-liner functions are necessary evil for to achieve it. > This doesn't strike me as good design. Visitor pattern can be quite useful when the things what visitors visit do not belong to same inheritance hierarhy and they form far more complex object graph in running program than raw array of 3. > Any ideas of how to resolve this? (Feel free to suggest > ideas that break the Visitor pattern). The first alternative is to have all classes visited in same inheritance hierarchy (in example they already are, but in real application that may be quite expensive goal) and then have virtual member functions like 'up' and 'down' in all of them. The second alternative means manually made polymorphism from outside and that involves switch-cases on 'typeid' (or self-made "kind") or if-else-if chains on 'dynamic_cast' and that will be very terrible code in long run. If you see such thing somewhere then better refactor it into virtual functions or visitor pattern. Given example is too abstract, useless and meaningless so it all is just pointless bloat, not worth resolving: #include <iostream> int main() { std::cout << "do Up on This\n" "do Up on That\n" "do Up on TheOther\n" "do Down on This\n" "do Down on That\n" "do Down on TheOther\n"; } Same effect, 10 times shorter and no memory leaks. |
Paul <pepstein5@gmail.com>: Nov 08 01:06AM -0800 On Saturday, November 8, 2014 2:52:00 AM UTC, Öö Tiib wrote: > "do Down on TheOther\n"; > } > Same effect, 10 times shorter and no memory leaks. Thanks a lot for your reply. I've never seen a visitor example where the things that visitors visit are not part of the same hierarchy but I see that the basic pattern that when you accept a visitor, you ask the visitor to visit, does not depend on the visited things being in the same hierarchy. The code on the website is even worse than you think. The original version (before I corrected it in the posting) has a for(i = 0; ...) loop instead of for(int i = 0; ...) and therefore doesn't compile. Another visitor illustration that is prominent on google searches is http://alumni.cs.ucr.edu/~lgao/teaching/visitor.html This does not leak memory and does use a virtual destructor. I would hope that this second example is ok but I haven't had a chance to run it yet. I'd be interested to hear opinions on this second example. If the second example handles the topic well, perhaps a good tip is that it's a good idea to look at univ or college websites because the author is likely to have received extensive feedback from students. I would guess that students are far more likely to correct errors than readers of books. I'm about to read the Gang-of-four book on design patterns to learn about design patterns in c++. If anyone wants to tell me: "No, read ... instead" then I'm all ears. Paul |
jacob navia <jacob@spamsink.net>: Nov 08 10:21AM +0100 Le 08/11/2014 00:13, Paul a écrit : Sorry to answer a question with another question but isn't the visitor pattern best implemented in the form of an iterator? Isn't an iterator "THE" visitor pattern? Thanks |
Paul <pepstein5@gmail.com>: Nov 08 01:29AM -0800 On Saturday, November 8, 2014 9:21:29 AM UTC, jacob navia wrote: > pattern best implemented in the form of an iterator? > Isn't an iterator "THE" visitor pattern? > Thanks I'm not sure that I understand you. The original code contains iteration through a list as below (at the end of this message). Whenever I've seen the Visitor pattern, I've seen a class hierarchy of visitors and a class hierarchy of visited-things. However, the first reply to my post said : "The Visitor pattern can be quite useful when the things that visitors visit do not belong to the same inheritance hierarchy." If that is the statement that concerns you, the question is one for Oo Tiib. Paul for (int i = 0; i < 3; i++) // and passes each list[i]->accept(up); |
Paul <pepstein5@gmail.com>: Nov 08 01:36AM -0800 On Saturday, November 8, 2014 9:30:16 AM UTC, Paul wrote: > for (int i = 0; i < 3; i++) > // and passes each > list[i]->accept(up); Sorry, I used careless terminology yet again. I should have said that the original code iterates through an array (not a list). However, I still don't get Jacob Navia's point but I'm very grateful to him for contributing to the discussion. Paul |
jacob navia <jacob@spamsink.net>: Nov 08 10:55AM +0100 Le 08/11/2014 10:36, Paul a écrit : > On Saturday, November 8, 2014 9:30:16 AM UTC, Paul wrote: list[i]->accept(up); > Sorry, I used careless terminology yet again. I should have said that the original code iterates through an array (not a list). However, I still don't get Jacob Navia's point but I'm very grateful to him for contributing to the discussion. > Paul Well, my point is that the iterator *is* the visitor pattern, i.e. as you say, "the original code *iterates* through an array". In the iterator, the line you are trying to avoid is *implicit*, it is the iterator that applies the visitor to each element... |
"Öö Tiib" <ootiib@hot.ee>: Nov 08 04:24AM -0800 On Saturday, 8 November 2014 11:06:26 UTC+2, Paul wrote: > that the basic pattern that when you accept a visitor, you ask the visitor > to visit, does not depend on the visited things being in the same > hierarchy. Yes. Sometimes some artificial base class (like "Object", "Element", "Item" or "Visitable") is used for all the visited types but there are actually no need for that. > I'm about to read the Gang-of-four book on design patterns to learn > about design patterns in c++. If anyone wants to tell me: "No, > read ... instead" then I'm all ears. All the patterns are just for solving some particular programming problems. Imagine case that your more or less mature application contains some large data hierarchy. For example there are "Houses", house consists of "Rooms", those have "Furniture" and "Equipment" in them, somewhere there is "Closet", it may have "Drawers", some of those contain "Socks" or there is "Fridge" that contains "Shelves" that contain "Foods" and "Beverages". All of it is more or less dynamic run-time. Now you need to locate and pick up all empty beer bottles in particular house at particular moment. For that you may have to "visit" all places where empty beer bottle can be in the house. You may write "EmptyBeerBottleFindingVisitor" or some more generic "SearchVisitor". Most important is that you had no idea that you will need it when you started to write the program. There are numerous other ways how to implement it (and lot of those are not bad). You can extend your program with special tracking/book-keeping for all instances of objects. You may make all "containers" and "locations" recursively "searchable". What you should pick? No one can tell for sure. It depends on what is simpler and more fruitful with your almost mature code base. |
"Öö Tiib" <ootiib@hot.ee>: Nov 08 10:56AM -0800 On Saturday, 8 November 2014 11:55:56 UTC+2, jacob navia wrote: > you say, "the original code *iterates* through an array". > In the iterator, the line you are trying to avoid is *implicit*, it is > the iterator that applies the visitor to each element... I already trashed the example; with short 3 object array of objects in same inheritance tree and pure abstract base visitor it is so hopelessly far from both hint of various responsibilities that visitors are capable of taking and difficulties that visitors may need to solve and ways to solve those. It was so stupid that one of most complex patterns could be easily confused with one of most simple things. Certainly there is difference. Iterator is over particular container. It is very blunt and simple. Most iterators are just wrappers around single pointer. The code is short since an iterator needs only to know how to navigate in that container. The visitors typically visit (part of) runtime object graph. A visitor visiting object of type X that may point at objects of type Y can go and visit those too. All that visitable classes have to contain is one-liner "accept" member function; rest of the responsibilities are upon the visitor. Once the classes are made visitable by base visitor there are no changes needed in the code of classes for to add yet another visitor that can visit with other goal. However the visitors need to be familiar with all the classes visited. The navigation may be far more trickier than business of iterator since data of real applications is not always a simple tree. Several of X may have pointer to same Y or Y may point to Z that may point back to one of X. On such cases the visitors need to be smart and to keep track of places been at to reduce the work and to avoid hanging lost forever in that runtime data maze with such loops. Therefore it is wise to keep that smartness of navigation in base visitor. When data structure is changed then most related changes will be in base visitor and actual visitors need to be changed only if new types to visit are added. One may say that they never have such loops and it is program design error. So? We are not gods, we make typos. How to find out that our program does not have such things run-time? Easiest answer is "with visitor". ;-) |
Laurent <laurent.plagne@gmail.com>: Nov 08 12:05AM -0800 Le vendredi 7 novembre 2014 15:54:01 UTC+1, Juha Nieminen a écrit : > by writing a static_assert inside the template where you check that > sizeof...(parameters) is within the limits you want.) > --- news://freenews.netfront.net/ - complaints: news@netfront.net --- Thank you so very much ! I have tried this yesterday in order to write a small library that deals with multidim array (on top of Eigen and TBB) that allow automatic vectorization (and parallelization) of algorithms. The basic idea is to handle proper interweaving of the underlying array containers in order to vectorize loops that do not match the inner dimension of arrays... The variadic template feature is so cool and I was so excited about this that I spent a signicative amount of my day in disturbing my collegues showing (off) the few lines of codes I wrote ;). Something like vector_for_each(user_algo(),arrays...)) can be written as for_each(user_algo(),(arrays.getSIMDView())...) //methods! C++ new stuff enables real functional approach ! With type classes it would be perfect ;) Thank you gain ! Laurent |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment