home bbs files messages ]

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,199 of 33,346   
   kamil.rojewski@googlemail.com to All   
   Re: Template setters   
   08 Sep 13 23:41:23   
   
   On Sunday, September 8, 2013 1:50:03 AM UTC+2, Öö Tiib wrote:   
      
   > Have you considered avoiding those "setters"? Setters only make it   
   > difficult for human brain that expects a "person" to "marry" or to   
   > "divorce" and does not expect some random spaghetti function   
   > somewhere to "set marital status", "set spouse", "set family name"   
   > etc. instead.   
      
   Setters themselves have pros and cons and it's a long and still   
   ongoing debate whether to use them or not. I would like to avoid that   
   discussion here since I've seen it can turn into "religious" wars,   
   rather than exchange of arguments. Let's just assume they are being   
   used for some reasons.   
      
   > You seriously oversimplify that pre-C++11 life. Move was also   
   > traditionally there with pointer to non-const, with the sole   
   > pre-C++11 smart pointer and with various things made by   
   > developers. It was already used so it was made better supported by   
   > language. Now there are additionally rvalue references and two new   
   > smart pointers.   
      
    From one point of view, move was there, but it had to be done manually   
   every time, often leading to bizarre constructs like non-const   
   auto_ptr copy (pseudo-move) constructor. That approach was both   
   unintuitive and lead to code repetition, if someone wanted to go that   
   path (const + non-const versions of everything, which wanted to   
   support move). Now, we have the means to do it the right way and I   
   think we should try to take the opportunity (when appropriate), thus   
   my original idea.   
      
   > Do you presume that "set spouse" (that sets relation with other   
   > "person" object) and "set marital status" (that only sets some enum   
   > attribute to /married/ or /single/) can somehow be handled   
   > uniformly?   
   >   
   > I feel that the suggested idiom can make parameter passing even more   
   > complicated than it already is.   
      
   The use case for the setters, you give as an example, would stay the   
   same. This new approach would only allow the use of new language   
   features with the possibility of perfect forwarding the setter   
   argument to any operator = overload. Let's take for example:   
      
   class Gadget   
   {   
   public:   
        void setWidget(const Widget &w) { mWidget = w; }   
      
   private:   
        Widget mWidget;   
   };   
      
   Gadget object;   
      
   Widget w;   
   object.setWidget(w); // #1   
   object.setWidget(Widget()); // #2   
      
   With this old-style code, both versions pass the Widget object as   
   const &, which in turn causes copy-assignment to mWidget every   
   time. But, we don't need to make a copy in case #2, so why should we?   
   What if we want to move that #1 lvalue also? That necessitates the   
   creation of a new setter taking Widget &&, therefore leading to code   
   repetition. And don't get me started on const xvalues...  I think my   
   templated approach with universal references provides a nice solution   
   to all that problems.   
   But you do have a point with making things complicated - it certainly   
   would. I don't think making a template would be the complication -   
   templates are all around. The real complication could come from   
   something like this:   
      
   class Widget   
   {   
   public:   
        ...   
      
        Widget &operator =(int i) { ... }   
   };   
      
   class Gadget   
   {   
   public:   
        template   
        void setWidget(T &&w) { mWidget = std::forward(w); }   
      
   private:   
        Widget mWidget;   
   };   
      
   Gadget object;   
   object.setWidget(1);   
      
   That is confusing. But he question here is - is it more confusing that   
   the operator = in Widget itself? Is the confusion the fault of the   
   setter or Widget? Or maybe, the setter uncovered some design flaw?   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca