Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.lang.c++.moderated    |    Moderated discussion of C++ superhackery    |    33,346 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 33,144 of 33,346    |
|    frank67x@googlemail.com to All    |
|    Re: post-increment without temporary obj    |
|    24 Jul 13 23:53:14    |
   
   { Please limit your text to fit within 80 columns, preferably around 70,   
    so that readers don't have to scroll horizontally to read each line.   
    This article has been reformatted manually by the moderator. -mod }   
      
   Am Donnerstag, 25. Juli 2013 01:06:00 UTC+2 schrieb Daniel Krügler:   
   > Am 24.07.2013 20:42, schrieb frank67x@googlemail.com:   
   > > Trying to avoid a temporary copy of *this in post-increment.   
   > > But is this code below valid?   
   >   
   > Valid in which sense? Let's ignore for the moment the fact, that it is   
   > (in general) possible that operator++() may throw an exception (I'm   
   > mentioning this, because this would be a show stopper when considering   
   > to use this idiom in a general iterator facade such as   
   > boost::iterator_facade).   
      
   Ups - you're right. For delaying the operation that way, i can't catch in the   
   operator function anymore. So the delayed operation has to be w/o exceptions   
   (however see other (simpler) version below - it could catch on struct Delay).   
      
   > If I understand your idea, you want to create   
   > an UPInt object before you perform the incrementation, but that does not   
   > need your Lazy type, because I simply could construct UPInt from *this,   
   > after this would invoke pre-increment, and then return the value.   
      
   No, i want to avoid the temporary object - not create before.   
      
   > Whether you construct a named UPInt object (as I described above) or an   
   > unnamed one (in your design), in both cases, RVO is optional (but   
   > possible), so I don't see that you exclude the possibility of an   
   > intermediate copy (nor do I understand the advantage of preventing this)   
   > in either case.   
      
    g++ -fno-elide-constructors -O0 -o Lazy main.cpp   
      
   standard implementation with named temporary object:   
      
    x = 1   
    pre-increment   
    x = 2   
    before post-increment operation...   
    copy c'tor   
    pre-increment   
    copy c'tor   
    copy c'tor   
    y = 2   
    x = 3   
      
      
   "lazy" version:   
      
    x = 1   
    pre-increment   
    x = 2   
    before post-increment operation...   
    post-increment before exit   
    copy c'tor   
    DoIncrement()   
    pre-increment   
    copy c'tor   
    y = 2   
    x = 3   
      
   So saves one copy c'tor invocation.   
   However you're right (N)RVO does the job.   
   (I've to test, if (N)RVO still works, if the operation become more complex.)   
      
   > I also think that your model iterator UPInt doesn't properly account for   
   > some very special characteristics of a valid input iterator: The input   
   > iterator requirements basically allow you to implement an iterator where   
   > all copies reference the same underlying data source (e.g. an input   
   > stream) without need to copy it. Now if your UInt type would hold such a   
   > reference, you would have the problem that the also required operation   
   >   
   > *r++   
   >   
   > cannot be correctly implemented (without an additional proxy return   
   > type), because here you would invoke operator* *after* operator++(int),   
   > and the returned value is the wrong one (it would be the value that   
   > followed the required one).   
      
   Why? - it's still the same value in the output.   
   The delayed operation still belongs to operator++(int). It's just somehow in   
   between the return operation and actually escaping from the operator++(int).   
      
   > But maybe I misunderstand what you are intending here, so could you   
   > please make your point a little bit clearer?   
      
   Here is another version with boost::proto:   
      
   ===================================   
      
   #include
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca