Topic: comp.std.c++: Default arguments


Author: JamesC@MonsterSystems.com (James J. Couball)
Date: 1996/08/16
Raw View
"Alexander Terekhov" <terekhov@de.ibm.com> wrote:

> In other words I would like to have a possibility to
> explicitly omit ANY argument(s) with default values or a possibility
> to explicitly tell compiler that I want use argument's default value.
> The 2-nd one seems to be not so hard to implement because "default" is
> already reserved for the "switch". I do not know if it would be
> reasonable to provide something like:
>
> void foo( int p1=1,int p2=2 );
>
> void fooCaller()
> {
>   foo( default+1,10 );
> }
>
> But why not? Simply in the scope of the argument's expression programmer
> would be able to use "default" keyword to refer the argument default
> value.

Alex,

I really like the idea of overloading the
'default' reserve word for this use.  I have
experienced many occasions where I wanted to use
the default argument for a function which came
before an argument which I did not want to accept
the default for.

This is especially useful where function arguments
are not related so that determining which is more
likely to use the default and which is not is
difficult or impossible to determine.

I suspect that it will be impossible to get this
into the current working draft, but I am glad you
brought this up so that it can be on people's mind
for the next round.

James Couball
Enable, Inc.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Chelly Green <chelly@eden.com>
Date: 1996/08/09
Raw View
Alexander Terekhov wrote:
>
>  Hi,
>
>  C++ supports default arguments for functions (and templates).
>  Fine, so I can write:
>
>  void foo( int p1=1,int p2=2 );
>
>  void fooCaller()
>  {
>    foo();
>  }
>
>  But imagine the situation when I am absolutely happy with the
>  function behavior controlled by the "p1" default value but
>  need to specify another value for "p2". And at the same time
>  I would like not to add dependencies to the "p1" default value
>  to my code in order to be protected in the case of interface
>  change which affects "p1" default value. This is especially
>  important when the interface of foo uses not simple expression
>  for "p1" default value:
>
>  void foo( int p1=f1( 1,2,f2( 3,4,5 ) ),int p2=2 )
>
>  So I would like to write something like:
>
>  void foo( int p1=1,int p2=2 );
>
>  void fooCaller()
>  {
>    foo( ,10 );
>  }
>
>  or:
>
>  void foo( int p1=1,int p2=2 );
>
>  void fooCaller()
>  {
>    foo( default,10 );
>  }

How about (enum, my old friend for adding "keywords" :-):

    enum _defarg { defarg };

    void foo( int p1 = 1, int p2 = 2 );
    inline void foo( _defarg, int p2 ) { foo( 1, p2 ); }

Usage:

    void fooCaller()
    {
         foo( defarg, 10 );
    }

That's kinda nice, but would require lots of inlines when there are more
default arguments.

...
>  May be the latest draft already defines something which could be
>  used in order to solve my problem?

If it supports enums, it does (see above)  :-)

--
Chelly Green | mailto:chelly@eden.com | http://www.eden.com/~chelly


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: damian@molly.cs.monash.edu.au (Damian Conway)
Date: 1996/08/09
Raw View
Alexander Terekhov <terekhov@de.ibm.com> writes:

> So I would like to write something like:
>  void foo( int p1=1,int p2=2 );

> void fooCaller()
> {
>   foo( default,10 );
> }

Okay. Here's a close approximation in std C++:

    // IN default.h:

 class DefaultMarker {};
 static DefaultMarker _default_;

 template <class Type, Type def>
 class Default
 {
 public:
  Default(const Type & t) : myVal(t) {}
  Default(DefaultMarker) : myVal(def) {}
  operator Type(void) { return myVal; }
 private:
  Type myVal;
 };


    // IN YOUR CODE:

 void foo(Default<int,1> p1 = _default_, Default<int,2> p2 = _default_)
 {
  cout << p1 << "," << p2 << endl;
 }

 void fooCaller(void)
 {
  foo( _default_ , 10 );
 }


> And the scope "::" operator would be useful too:

> void foo1( int p1=1,int p2=2 );
> void foo2( int p1=3,int p2=4 );

> void fooCaller()
> {
>   foo1( foo2( foo1::default + foo2::default ),10 );
> }

> which is the equivalent of:

>   foo1( foo2( 1 + 2 ),10 );

Err, that's actually equivalent to:

    foo1( foo2( 1+2, 4 ), 10 );

Besides which, foo2 is going to have to return an int.

Here's a reasonable approximation in std C++:


    // IN default.h:

 class DefaultMarker {};
 static DefaultMarker _default_;

 template <class Type, Type def>
 class Default
 {
 public:
  Default(const Type & t) : myVal(t) {}
  Default(DefaultMarker) : myVal(def) {}
  operator Type(void) { return myVal; }
 private:
  Type myVal;
 };


    // IN YOUR CODE:

 const int foo1_default_1 = 1;
 const int foo1_default_2 = 2;
 const int foo2_default_1 = 3;
 const int foo2_default_2 = 4;

 void foo1(Default<int,foo1_default_1> p1 = _default_,
    Default<int,foo1_default_2> p2 = _default_)
 {
  cout << p1 << endl;
  cout << p2 << endl;
 }

 int foo2(Default<int,foo2_default_1> p1 = _default_,
    Default<int,foo2_default_2> p2 = _default_)
 {
  return p1 * p2;  // WHATEVER :-)
 }

 main()
 {
  foo1( foo2( foo1_default_1 + foo2_default_2 ),10);
 }



Damian Conway
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  who: Damian Conway                 email: damian@cs.monash.edu.au
where: Computer Science Dept.          web: http://www.cs.monash.edu.au/~damian
       Monash University             phone: +61-3-9905-5184
       Clayton 3168                    fax: +61-3-9905-5146
       AUSTRALIA                     quote: "A pessimist is never disappointed."
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Alexander Terekhov" <terekhov@de.ibm.com>
Date: 1996/08/12
Raw View
 Chelly Green wrote:

 > How about (enum, my old friend for adding "keywords" :-):
 >
 >     enum _defarg a defarg u;
 >
 >     void foo( int p1 = 1, int p2 = 2 );
 >     inline void foo( _defarg, int p2 ) { foo( 1, p2 ); }
 >
 > Usage:
 >
 >     void fooCaller()
 >     {
 >          foo( defarg, 10 );
 >     }
 >
 > That's kinda nice, but would require lots of inlines when there are more
 > default arguments.

 The main problem is how to avoid dependencies to default argument expressions
 which are a part of an external interface and could be changed.
 Unfortunately, the workaround you propose does not solve it.  Nor will it be
 easy to implement such wrappers for class functions.

 Damian Conway wrote:

 > Okay. Here's a close approximation in std C++:
 >
 >    // IN default.h:
 >
 > class DefaultMarker {};
 > static DefaultMarker _default_;
 >
 > template <class Type, Type def>
 > class Default
 > {
 > public:
 >  Default(const Type & t) : myVal(t) {}
 >  Default(DefaultMarker) : myVal(def) {}
 >  operator Type(void) { return myVal; }
 > private:
 >  Type myVal;
 > };
 >
 >
 >    // IN YOUR CODE:
 >
 > void foo(Default<int,1> p1 = _default_, Default<int,2> p2 = _default_)
 > {
 >  cout << p1 << "," << p2 << endl;
 > }
 >
 > void fooCaller(void)
 > {
 >  foo( _default_ , 10 );
 > }

 The same problem with dependencies/classes. And how can I use
 your template for the following function:

    void foo( int p = fooDefaultP() );

 Ok, so it is possible to play with Default< ... > static or even global
 consts (like your code below). But the result code will be
 hard to read/understand and it will create problems
 if fooDefaultP() happens to have preconditions and/or side effects.

 >
 > > And the scope "::" operator would be useful too:

 > > void foo1( int p1=1,int p2=2 );
 > > void foo2( int p1=3,int p2=4 );

 > > void fooCaller()
 > > {
 > >   foo1( foo2( foo1::default + foo2::default ),10 );
 > > }
 >
 > > which is the equivalent of:
 > >
 > >   foo1( foo2( 1 + 2 ),10 );

 > Err, that's actually equivalent to:
 >
 >    foo1( foo2( 1+2, 4 ), 10 );

 Yes, I really did make 2 mistakes. The 1st one in the expression above, which
 should have been:

      foo1( foo2( 1+3 ), 10 );

 Or (including the 2nd argument of foo2):

      foo1( foo2( 1+3,4 ), 10 );

 >
 > Besides which, foo2 is going to have to return an int.

 This is the other one (mistake, that is.)

 > Here's a reasonable approximation in std C++:
 >
 >
 >    // IN default.h:
 >
 > class DefaultMarker au;
 > static DefaultMarker _default_;
 >
 > template <class Type, Type def>
 > class Default
 > {
 > public:
 >  Default(const Type & t) : myVal(t) {}
 >  Default(DefaultMarker) : myVal(def) {}
 >  operator Type(void) { return myVal; }
 > private:
 >  Type myVal;
 > };
 >
 >
 >    // IN YOUR CODE:
 >
 > const int foo1_default_1 = 1;
 > const int foo1_default_2 = 2;
 > const int foo2_default_1 = 3;
 > const int foo2_default_2 = 4;
 >
 > void foo1(Default<int,foo1_default_1> p1 = _default_,
 >    Default<int,foo1_default_2> p2 = _default_)
 > {
 >  cout << p1 << endl;
 >  cout << p2 << endl;
 > }
 >
 > int foo2(Default<int,foo2_default_1> p1 = _default_,
 >    Default<int,foo2_default_2> p2 = _default_)
 > {
 >  return p1 * p2;oo// WHATEVER :-)
 > }
 >
 > main()
 > {
 >  foo1( foo2( foo1_default_1 + foo2_default_2 ),10);
 > }

 You are using global consts, the thing I would like to avoid. And
 the initializing code is also affected by the dependencies problem.

 Chelly and Damian, thanks for your proposals but unfortunately
 they do not solve all problems.

 So why not provide an additional meaning for the "default" keyword and
 make it a part of C++?

 Alexander Terekhov
 terekhov@de.ibm.com
 IBM Deutschland Entwicklung GmbH.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Alexander Terekhov" <terekhov@de.ibm.com>
Date: 1996/08/08
Raw View
 Hi,

 C++ supports default arguments for functions (and templates).
 Fine, so I can write:

 void foo( int p1=1,int p2=2 );

 void fooCaller()
 {
   foo();
 }

 But imagine the situation when I am absolutely happy with the
 function behavior controlled by the "p1" default value but
 need to specify another value for "p2". And at the same time
 I would like not to add dependencies to the "p1" default value
 to my code in order to be protected in the case of interface
 change which affects "p1" default value. This is especially
 important when the interface of foo uses not simple expression
 for "p1" default value:

 void foo( int p1=f1( 1,2,f2( 3,4,5 ) ),int p2=2 )

 So I would like to write something like:

 void foo( int p1=1,int p2=2 );

 void fooCaller()
 {
   foo( ,10 );
 }

 or:

 void foo( int p1=1,int p2=2 );

 void fooCaller()
 {
   foo( default,10 );
 }

 In other words I would like to have a possibility to
 explicitly omit ANY argument(s) with default values or a possibility
 to explicitly tell compiler that I want use argument's default value.
 The 2-nd one seems to be not so hard to implement because "default" is
 already reserved for the "switch". I do not know if it would be
 reasonable to provide something like:

 void foo( int p1=1,int p2=2 );

 void fooCaller()
 {
   foo( default+1,10 );
 }

 But why not? Simply in the scope of the argument's expression programmer
 would be able to use "default" keyword to refer the argument default
 value. And the scope "::" operator would be useful too:

 void foo1( int p1=1,int p2=2 );
 void foo2( int p1=3,int p2=4 );

 void fooCaller()
 {
   foo1( foo2( foo1::default + foo2::default ),10 );
 }

 which is the equivalent of:

   foo1( foo2( 1 + 2 ),10 );

 May be the latest draft already defines something which could be
 used in order to solve my problem?

 regards,
 Alexander Terekhov
 terekhov@de.ibm.com
 IBM Deutchland Entwicklung GmbH.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]