<p dir="ltr">Sounds good to me. Should we *also* make the Projection() copy constructor private cf. operator=(), or dies that not achieve anything / cause other problems?</p>
<p dir="ltr">I agree slicing and other gotchas are intrinsic to the nature of C++, but "the Rivet way" is to protect users from the need to know these things whenever that's possible without restricting useful functionality (a delicate balance...)</p>
<p dir="ltr">AB</p>
<div class="gmail_quote">On 8 Jul 2015 17:15, "Chris Pollard" <<a href="mailto:cpollard@cern.ch">cpollard@cern.ch</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi all,<div><br>David and I just had a quick chat about this, and I think I finally understand what is going on here. David, please say something if I don't summarize our discussion correctly...</div><div><br></div><div>We both agree that the best thing to do is to have remainingFinalState() return "const VetoedFinalState&", which is the actual type of the underlying returned object. Currently it returns "const FinalState&". This change *should* generate compile-time warnings when a user tries something like</div><div><br></div><div><font face="monospace, monospace">FinalState fs = zfinder.remainingFinalState();</font></div><div><br></div><div>because fs is being copy-constructed from a more complex class. @Frank, I think this will also make your attached broken example work as expected.</div><div><br></div><div>The following will work correctly and, now that remainingFinalState() returns the correct type, is hopefully what users will do if they absolutely have to make a copy.</div><div><br></div><div><span style="font-family:monospace,monospace">VetoedFinalState vfs = zfinder.remainingFinalState();</span></div><div><br></div><div>David's opinion (and he's convinced me, too) is that object slicing is an inherent "feature" of c++ that is going to be very difficult to work around, so just being careful with return types is the right way to deal with it.<br></div><div><br></div><div>Please pipe in of course if you see any issue with this.</div><div><br></div><div>Chris</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 8, 2015 at 9:27 AM, David Grellscheid <span dir="ltr"><<a href="mailto:david.grellscheid@durham.ac.uk" target="_blank">david.grellscheid@durham.ac.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The sequence<br>
<br>
  Type label = foobar;<br>
<br>
always calls a copy constructor of Type, it _never_ calls operator=().<br>
<br>
If the copy constructor Type(Type) is not user-defined, it will be<br>
created implicitly.<br>
<br>
In your case, a FinalState(const FinalState &) will be created and used<br>
as long as the result type of zfinder.remainingFinalState() is a<br>
descendant of FinalState.<br>
<br>
  David<br>
<span><br>
<br>
On 08/07/15 09:14, Chris Pollard wrote:<br>
> but... going back to Frank's Example1: I don't see a<br>
> FinalState(Projection) constructor. Won't operator =(Projection) be<br>
> called in the first line of<br>
><br>
>       FinalState remainder = zfinder.remainingFinalState();<br>
>       addProjection(remainder, "RFS");<br>
><br>
> since no appropriate constructor exists? Or will some implicit copy<br>
> constructor be called not via operator=?<br>
><br>
> Chris<br>
><br>
> On Tue, Jul 7, 2015 at 9:52 PM, David Grellscheid<br>
</span>> <<a href="mailto:david.grellscheid@durham.ac.uk" target="_blank">david.grellscheid@durham.ac.uk</a> <mailto:<a href="mailto:david.grellscheid@durham.ac.uk" target="_blank">david.grellscheid@durham.ac.uk</a>>><br>
<div><div>> wrote:<br>
><br>
>     Maybe the confusion comes from the fact that<br>
><br>
>       Foo a = 7;<br>
><br>
>     does not call operator=(), but calls the constructor Foo(int). It's<br>
>     just a different way of writing a constructor. operator=() is only<br>
>     called here:<br>
><br>
>       Foo a;<br>
>       a = 7;<br>
><br>
>     I still haven't had a chance to look at it in detail, sorry!<br>
><br>
>     See you,<br>
><br>
>       David<br>
><br>
><br>
><br>
>     On 07/07/2015 21:49, Andy Buckley wrote:<br>
><br>
>         Hmm, I certainly implemented it hoping that code with copy<br>
>         assignments (as<br>
>         opposed to copy constructions, which should perhaps also be<br>
>         banned to<br>
>         forbid an alternative-syntax route to achieving the same<br>
>         misguided goal)<br>
>         would now fail to compile. I based that on some StackOverflow<br>
>         reading since<br>
>         I was short of time to make an explicit test case of my own.<br>
><br>
>         I was *hoping* (and convinced from that reading) that it would<br>
>         not be legal<br>
>         for a private virtual method on a base class to be overloaded as<br>
>         public<br>
>         (and certainly not *automatically*) on a derived class. It would<br>
>         be a huge<br>
>         pain if those operators need to be *explicitly* private'd on<br>
>         every derived<br>
>         Projection.<br>
><br>
>         Aaaaand back to holiday ;-)<br>
>         AB<br>
><br>
><br>
</div></div></blockquote></div><br></div>
</blockquote></div>