Topic: Default values for template function parameters used to deduce template arguments


Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/05
Raw View
On 4 Dec 1998 16:59:25 GMT, Vlad Harchev <vladhar@imimail.ssau.ru> wrote:

>Is the following code correct?
>
>template <class T1,class T2>
>void f(T1 v1,T2 v2=3) { };

This is not correct in general because there may not be a conversion
from 'int' (the number '3') to T2.  For example:
   f<std::plus<int> >(5);

Supposing we aren't this explicit.  Say we write
   f(5);
The compiler can deduce that T1 is 'int'.  If the compiler is allowed
to deduce the type of T2 from the default argument -- that is, T2 is
an 'int' -- then the call works and we call f<int,int>(5,3).  If the
compiler is not allowed to deduce types from default arguments, then
the call is undefined.  The latter point of view is the correct one:

14.8.2.4  Deducing template arguments from a type  [temp.deduct.type]

(17)
A template type-parameter cannot be deduced from the type of a function
default argument.  [Example:

template <class T> void f(T=5, T=7);
void g()
{
     f(1); // OK: call f<int>(1,7)
     f(); // error: cannot deduce T
     f<int>(); // OK: call f<int>(5,7)
}


I don't see any deep reason why rule 17 exists.  I guess the ability
to deduce types from default arguments would conflict would default
template arguments (see below for a comment on default arguments in
function templates).



>I mean - whether default arguments for template function parameters are
>allowed? I haven't found anything definite in CD2. I think allowing this
>can be very useful, consider the following:
>
>template <class T1,class T2> struct is_equ_types { enum { ans=0 }; };
>template <class T> struct is_equ_types<T,T> { enum { ans=1 }; };
>
>struct nothing {} //unique class
>
>//this dumps all passed arguments that were actually passed. More parameters
>//can be added thus usability increased
>
>template <class O,class T1,class T2,class T3,class T4>
>void dump(O& o,const T1& v1=nothing(),const T2& v2=nothing(),
>         const T3& v3=nothing(),const T4& v4=nothing())

A few months ago on this newsgroup, Stroustrup pointed out that default
arguments for function templates should have been allowed; and in
their examples to one another, the committee used functions with default
template arguments.  Thanks to template argument deduction, default
arguments for function templates are not generally needed.  So I guess
they forgot about it.  See this message on www.dejanews.com:

   98/10/17
   Q: templates and default
   comp.lang.c++.moderated
   Bjarne Stroustrup



>Note: the following code compiles with Borland C++ 5.2, but fails on
>GCC 2.7.2, EGCS 1.1b.

Como also doesn't like it.

"tmp.c", line 10: error: no instance of function template "f" matches the
          argument list
            argument types are: (int)
         f(4);
         ^


>#include <iostream>
>template <class T,class T1>
>void f(T v,T1 v1=4)
>{
>  cout << v << " " << v1;
>};
>void main()
>{
> f(3,3);
> f(4);
>}

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Vlad Harchev" <vladhar@imimail.ssau.ru>
Date: 1998/12/04
Raw View
Is the following code correct?

template <class T1,class T2>
void f(T1 v1,T2 v2=3) { };

I mean - whether default arguments for template function parameters are
allowed? I haven't found anything definite in CD2. I think allowing this
can be very useful, consider the following:

template <class T1,class T2> struct is_equ_types { enum { ans=0 }; };
template <class T> struct is_equ_types<T,T> { enum { ans=1 }; };

struct nothing {} //unique class

//this dumps all passed arguments that were actually passed. More parameters
//can be added thus usability increased

template <class O,class T1,class T2,class T3,class T4>
void dump(O& o,const T1& v1=nothing(),const T2& v2=nothing(),
         const T3& v3=nothing(),const T4& v4=nothing())
{
  if ( !is_equ_types<T1,nothing>::ans )
  {
    o << v1;
    if ( !is_equ_types<T2,nothing>::ans )
     {
       o << " " << v2;
       if ( !is_equ_types<T3,nothing>::ans )
        {
          o << " " << v3;
          if ( !is_equ_types<T4,nothing>::ans )
           {
             o << " " << v4;
           }
        }
     }
  };
}
//usage
void f()
{
  dump(cout,"foo",3,4,5); dump(cout,4.4);
}

  GCC 2.7.2, and EGCS 1.1b don't accept it.

Note: the following code compiles with Borland C++ 5.2, but fails on
GCC 2.7.2, EGCS 1.1b.
#include <iostream>
template <class T,class T1>
void f(T v,T1 v1=4)
{
  cout << v << " " << v1;
};
void main()
{
 f(3,3);
 f(4);
}

So, if this is not allowed or nothing is said in final standard, IMO it will
be nice to allow this.
 - Vlad




[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]