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 32,715 of 33,346   
   Francis Glassborow to All   
   Re: Why isn't class a subset of class...   
   09 Dec 12 13:01:26   
   
   l-september.org> daa5bb8a   
   From: francis.glassborow@btinternet.com   
      
   On 08/12/2012 21:35, Tobias Müller wrote:   
   > DeMarcus  wrote:   
   >>>> Actually that makes it even more desirable to allow TakeTemplate to   
   >>>> receive variadic templates or normal templates with any number of   
   >>>> arguments (as long as there are default arguments so it matches   
   >>>> TakeTemplate).   
   >>>   
   >>> But then, shouldn't the same also be possible with default function   
   >>> arguments?   
   >>>   
   >>   
   >> Actually it's already possible today if you consider the following.   
   >>   
   >> void takeFnc( void (*fnc)(int) ) {}   
   >> void fnc( int a, int b = 42 ) {}   
   >>   
   >> int main()   
   >> {   
   >>      takeFnc( fnc ); // Error!   
   >>      return 0;   
   >> }   
   >>   
   >> Now rearrange your code like this:   
   >>   
   >> void takeFnc( void (*fnc)(int) ) {}   
   >> void fnc( int a, int b ) {}   
   >> void fnc( int a ) { int b = 42; }   
   >   
   > Probably you mean:   
   > void fnc( int a ) { fnc(a, 42); }   
   >   
   >> int main()   
   >> {   
   >>      takeFnc( fnc ); // It's now allowed.   
   >>      return 0;   
   >> }   
   >>   
   >> So the semantical question is: is a function with default arguments   
   >> actually several overloaded functions? If so, we should be able to use   
   >> them all.   
      
   Depends what you understand by 'semantical'. Functions with default   
   arguments do behave like a set of overloaded functions with a common   
   body. But we can acquire that common body without using default   
   arguments (see below).   
      
   >   
   > I tend to disagree on the semantical part. A default parameter gives you   
   > the guarantee, that both functions are the same, just with one parameter   
   > fixed.   
      
   True but the problem is that you can only fix parameters at the tail of   
   the parameter list. This sometimes leads to curious orderings for   
   parameters.   
      
   > With overloaded functions on the other hand each overload can have an   
   > entirely different functionality. And usually this is also the case, since   
   > otherwise you could use default parameters.   
      
   They better not have entirely different functionality because that leads   
   into code that is even less comprehensible than the traditional   
   spaghetti code.   
      
   When I see a function call with a specific name I expect it to do the   
   same thing as other functions (in the same namespace) with the same   
   name. I do not expect the meaning (semantics) of a function to depend on   
   the types of the arguments. Note that this is one of the strengths of   
   member functions because here the type of the object invoking it is   
   significant.   
   e.g.   
   my_luger.draw();   
   and   
   red_pencil.draw();   
   are fine by me.   
      
   >   
   > Anyway, regardless whether they are semantically different or not, they are   
   > not the same in C++, and that's the relevant part.   
      
   True, they invoke a different compile time mechanism but may still   
   result in identical object code.   
      
   I favour using overloading unless there are really strong reasons not to   
   (very rare)   
      
   Just write the function without any default arguments.   
   Now write forwarding functions to cover the 'defaults'.   
      
      
   int foo(int i, char c, float f);   
   inline int foo(int i, char c){return foo(i, c, 1.5);}   
   inline int foo(int i, float f){return foo(i, 'n', f);}   
   etc. defaulting as many arguments as you wish.   
   You need a little care if more than one parameter has the same type.   
      
   BTW a feature was actually added to the language to support this idiom.   
   Being allowed to return a functioning whose return type is void was   
   added some time in the mid 90's so that, for example   
   void bar(int i, char c);   
   void bar(int i){ return bar(i, 'n');)   
   would work.   
   >   
   > It's a bit like the difference between:   
   > typedef A B;   
   > and:   
   > class B : public A {};   
   > They are both similar but not equivalent.   
      
   I do not like that example as the difference is very substantial and   
   there is no reasonable way to use the latter as a substitute for the former.   
      
   Francis   
      
      
   --   
         [ 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